xref: /aosp_15_r20/external/pdfium/xfa/fde/cfde_texteditengine_unittest.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2017 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fde/cfde_texteditengine.h"
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_codepage.h"
8*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_extension.h"
9*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxge/text_char_pos.h"
10*3ac0a46fSAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
11*3ac0a46fSAndroid Build Coastguard Worker #include "testing/xfa_test_environment.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fgas/font/cfgas_gefont.h"
13*3ac0a46fSAndroid Build Coastguard Worker 
14*3ac0a46fSAndroid Build Coastguard Worker class CFDE_TextEditEngineTest : public testing::Test {
15*3ac0a46fSAndroid Build Coastguard Worker  public:
16*3ac0a46fSAndroid Build Coastguard Worker   class Delegate final : public CFDE_TextEditEngine::Delegate {
17*3ac0a46fSAndroid Build Coastguard Worker    public:
Reset()18*3ac0a46fSAndroid Build Coastguard Worker     void Reset() {
19*3ac0a46fSAndroid Build Coastguard Worker       text_is_full = false;
20*3ac0a46fSAndroid Build Coastguard Worker       fail_validation = false;
21*3ac0a46fSAndroid Build Coastguard Worker     }
22*3ac0a46fSAndroid Build Coastguard Worker 
NotifyTextFull()23*3ac0a46fSAndroid Build Coastguard Worker     void NotifyTextFull() override { text_is_full = true; }
24*3ac0a46fSAndroid Build Coastguard Worker 
OnCaretChanged()25*3ac0a46fSAndroid Build Coastguard Worker     void OnCaretChanged() override {}
OnTextWillChange(CFDE_TextEditEngine::TextChange * change)26*3ac0a46fSAndroid Build Coastguard Worker     void OnTextWillChange(CFDE_TextEditEngine::TextChange* change) override {}
OnTextChanged()27*3ac0a46fSAndroid Build Coastguard Worker     void OnTextChanged() override {}
OnSelChanged()28*3ac0a46fSAndroid Build Coastguard Worker     void OnSelChanged() override {}
OnValidate(const WideString & wsText)29*3ac0a46fSAndroid Build Coastguard Worker     bool OnValidate(const WideString& wsText) override {
30*3ac0a46fSAndroid Build Coastguard Worker       return !fail_validation;
31*3ac0a46fSAndroid Build Coastguard Worker     }
SetScrollOffset(float fScrollOffset)32*3ac0a46fSAndroid Build Coastguard Worker     void SetScrollOffset(float fScrollOffset) override {}
33*3ac0a46fSAndroid Build Coastguard Worker 
34*3ac0a46fSAndroid Build Coastguard Worker     bool fail_validation = false;
35*3ac0a46fSAndroid Build Coastguard Worker     bool text_is_full = false;
36*3ac0a46fSAndroid Build Coastguard Worker   };
37*3ac0a46fSAndroid Build Coastguard Worker 
38*3ac0a46fSAndroid Build Coastguard Worker   CFDE_TextEditEngineTest() = default;
39*3ac0a46fSAndroid Build Coastguard Worker   ~CFDE_TextEditEngineTest() override = default;
40*3ac0a46fSAndroid Build Coastguard Worker 
SetUp()41*3ac0a46fSAndroid Build Coastguard Worker   void SetUp() override {
42*3ac0a46fSAndroid Build Coastguard Worker     const wchar_t kFontFamily[] = L"Arimo Bold";
43*3ac0a46fSAndroid Build Coastguard Worker     font_ = CFGAS_GEFont::LoadFont(kFontFamily, 0, FX_CodePage::kDefANSI);
44*3ac0a46fSAndroid Build Coastguard Worker     ASSERT_TRUE(font_);
45*3ac0a46fSAndroid Build Coastguard Worker 
46*3ac0a46fSAndroid Build Coastguard Worker     engine_ = std::make_unique<CFDE_TextEditEngine>();
47*3ac0a46fSAndroid Build Coastguard Worker     engine_->SetFont(font_);
48*3ac0a46fSAndroid Build Coastguard Worker     engine_->SetFontSize(12.0f);
49*3ac0a46fSAndroid Build Coastguard Worker   }
50*3ac0a46fSAndroid Build Coastguard Worker 
TearDown()51*3ac0a46fSAndroid Build Coastguard Worker   void TearDown() override {
52*3ac0a46fSAndroid Build Coastguard Worker     engine_.reset();
53*3ac0a46fSAndroid Build Coastguard Worker     font_.Reset();
54*3ac0a46fSAndroid Build Coastguard Worker   }
55*3ac0a46fSAndroid Build Coastguard Worker 
engine() const56*3ac0a46fSAndroid Build Coastguard Worker   CFDE_TextEditEngine* engine() const { return engine_.get(); }
57*3ac0a46fSAndroid Build Coastguard Worker 
58*3ac0a46fSAndroid Build Coastguard Worker  private:
59*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<CFGAS_GEFont> font_;
60*3ac0a46fSAndroid Build Coastguard Worker   std::unique_ptr<CFDE_TextEditEngine> engine_;
61*3ac0a46fSAndroid Build Coastguard Worker };
62*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,Insert)63*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, Insert) {
64*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
65*3ac0a46fSAndroid Build Coastguard Worker 
66*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"");
67*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
68*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetLength());
69*3ac0a46fSAndroid Build Coastguard Worker 
70*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
71*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
72*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, engine()->GetLength());
73*3ac0a46fSAndroid Build Coastguard Worker 
74*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
75*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
76*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(11U, engine()->GetLength());
77*3ac0a46fSAndroid Build Coastguard Worker 
78*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" New");
79*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello New World", engine()->GetText().c_str());
80*3ac0a46fSAndroid Build Coastguard Worker 
81*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(100, L" Cat");
82*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello New World Cat", engine()->GetText().c_str());
83*3ac0a46fSAndroid Build Coastguard Worker 
84*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
85*3ac0a46fSAndroid Build Coastguard Worker 
86*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetHasCharacterLimit(true);
87*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetCharacterLimit(5);
88*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
89*3ac0a46fSAndroid Build Coastguard Worker 
90*3ac0a46fSAndroid Build Coastguard Worker   // No delegate
91*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
92*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
93*3ac0a46fSAndroid Build Coastguard Worker 
94*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetCharacterLimit(8);
95*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
96*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello Wo", engine()->GetText().c_str());
97*3ac0a46fSAndroid Build Coastguard Worker 
98*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
99*3ac0a46fSAndroid Build Coastguard Worker 
100*3ac0a46fSAndroid Build Coastguard Worker   // With Delegate
101*3ac0a46fSAndroid Build Coastguard Worker   auto delegate = std::make_unique<CFDE_TextEditEngineTest::Delegate>();
102*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetDelegate(delegate.get());
103*3ac0a46fSAndroid Build Coastguard Worker 
104*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetCharacterLimit(5);
105*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
106*3ac0a46fSAndroid Build Coastguard Worker 
107*3ac0a46fSAndroid Build Coastguard Worker   // Insert when full.
108*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
109*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(delegate->text_is_full);
110*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
111*3ac0a46fSAndroid Build Coastguard Worker   delegate->Reset();
112*3ac0a46fSAndroid Build Coastguard Worker 
113*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetCharacterLimit(8);
114*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
115*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(delegate->text_is_full);
116*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello Wo", engine()->GetText().c_str());
117*3ac0a46fSAndroid Build Coastguard Worker   delegate->Reset();
118*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetHasCharacterLimit(false);
119*3ac0a46fSAndroid Build Coastguard Worker 
120*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
121*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
122*3ac0a46fSAndroid Build Coastguard Worker 
123*3ac0a46fSAndroid Build Coastguard Worker   // Insert Invalid text
124*3ac0a46fSAndroid Build Coastguard Worker   delegate->fail_validation = true;
125*3ac0a46fSAndroid Build Coastguard Worker   engine()->EnableValidation(true);
126*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
127*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
128*3ac0a46fSAndroid Build Coastguard Worker 
129*3ac0a46fSAndroid Build Coastguard Worker   delegate->fail_validation = false;
130*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
131*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
132*3ac0a46fSAndroid Build Coastguard Worker   engine()->EnableValidation(false);
133*3ac0a46fSAndroid Build Coastguard Worker 
134*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
135*3ac0a46fSAndroid Build Coastguard Worker 
136*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello\nWorld");
137*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(delegate->text_is_full);
138*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello\nWorld", engine()->GetText().c_str());
139*3ac0a46fSAndroid Build Coastguard Worker   delegate->Reset();
140*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
141*3ac0a46fSAndroid Build Coastguard Worker 
142*3ac0a46fSAndroid Build Coastguard Worker   // Insert with limited area and over-fill
143*3ac0a46fSAndroid Build Coastguard Worker   engine()->LimitHorizontalScroll(true);
144*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetAvailableWidth(52.0f);  // Fits 'Hello Wo'.
145*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
146*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(delegate->text_is_full);
147*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
148*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(delegate->text_is_full);
149*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello Wo", engine()->GetText().c_str());
150*3ac0a46fSAndroid Build Coastguard Worker   engine()->LimitHorizontalScroll(false);
151*3ac0a46fSAndroid Build Coastguard Worker 
152*3ac0a46fSAndroid Build Coastguard Worker   delegate->Reset();
153*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
154*3ac0a46fSAndroid Build Coastguard Worker 
155*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetLineSpace(12.0f);
156*3ac0a46fSAndroid Build Coastguard Worker   engine()->LimitVerticalScroll(true);
157*3ac0a46fSAndroid Build Coastguard Worker   // Default is one line of text.
158*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
159*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(delegate->text_is_full);
160*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" Wo\nrld");
161*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(delegate->text_is_full);
162*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello Wo\n", engine()->GetText().c_str());
163*3ac0a46fSAndroid Build Coastguard Worker   engine()->LimitVerticalScroll(false);
164*3ac0a46fSAndroid Build Coastguard Worker 
165*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetDelegate(nullptr);
166*3ac0a46fSAndroid Build Coastguard Worker }
167*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,InsertToggleLimit)168*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, InsertToggleLimit) {
169*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetHasCharacterLimit(true);
170*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
171*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetCharacterLimit(5);
172*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Not Inserted before ");
173*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
174*3ac0a46fSAndroid Build Coastguard Worker 
175*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetHasCharacterLimit(false);
176*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Inserted before ");
177*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetHasCharacterLimit(true);
178*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Not Inserted before ");
179*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Inserted before Hello World", engine()->GetText().c_str());
180*3ac0a46fSAndroid Build Coastguard Worker }
181*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,InsertSkipNotify)182*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, InsertSkipNotify) {
183*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetHasCharacterLimit(true);
184*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetCharacterLimit(8);
185*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
186*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World",
187*3ac0a46fSAndroid Build Coastguard Worker                    CFDE_TextEditEngine::RecordOperation::kSkipNotify);
188*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
189*3ac0a46fSAndroid Build Coastguard Worker 
190*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Not inserted");
191*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
192*3ac0a46fSAndroid Build Coastguard Worker 
193*3ac0a46fSAndroid Build Coastguard Worker   engine()->Delete(5, 1);
194*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"HelloWorld", engine()->GetText().c_str());
195*3ac0a46fSAndroid Build Coastguard Worker 
196*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"****");
197*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"*HelloWorld", engine()->GetText().c_str());
198*3ac0a46fSAndroid Build Coastguard Worker }
199*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,InsertGrowGap)200*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, InsertGrowGap) {
201*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"||");
202*3ac0a46fSAndroid Build Coastguard Worker   for (size_t i = 1; i < 1023; ++i) {
203*3ac0a46fSAndroid Build Coastguard Worker     engine()->Insert(i, L"a");
204*3ac0a46fSAndroid Build Coastguard Worker   }
205*3ac0a46fSAndroid Build Coastguard Worker   WideString result = engine()->GetText();
206*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(result.GetLength(), 1024u);
207*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(result[0], L'|');
208*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(result[1], L'a');
209*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(result[2], L'a');
210*3ac0a46fSAndroid Build Coastguard Worker   // ...
211*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(result[1022], L'a');
212*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(result[1023], L'|');
213*3ac0a46fSAndroid Build Coastguard Worker }
214*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,Delete)215*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, Delete) {
216*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->Delete(0, 50).c_str());
217*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
218*3ac0a46fSAndroid Build Coastguard Worker 
219*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
220*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L" World", engine()->Delete(5, 6).c_str());
221*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
222*3ac0a46fSAndroid Build Coastguard Worker 
223*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
224*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
225*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L" ", engine()->Delete(5, 1).c_str());
226*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"HelloWorld", engine()->GetText().c_str());
227*3ac0a46fSAndroid Build Coastguard Worker 
228*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"elloWorld", engine()->Delete(1, 50).c_str());
229*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"H", engine()->GetText().c_str());
230*3ac0a46fSAndroid Build Coastguard Worker }
231*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,Clear)232*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, Clear) {
233*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
234*3ac0a46fSAndroid Build Coastguard Worker 
235*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
236*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
237*3ac0a46fSAndroid Build Coastguard Worker 
238*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
239*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
240*3ac0a46fSAndroid Build Coastguard Worker 
241*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
242*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
243*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetLength());
244*3ac0a46fSAndroid Build Coastguard Worker }
245*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetChar)246*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetChar) {
247*3ac0a46fSAndroid Build Coastguard Worker   // Out of bounds.
248*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L'\0', engine()->GetChar(0));
249*3ac0a46fSAndroid Build Coastguard Worker 
250*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
251*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L'H', engine()->GetChar(0));
252*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L'd', engine()->GetChar(engine()->GetLength() - 1));
253*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L' ', engine()->GetChar(5));
254*3ac0a46fSAndroid Build Coastguard Worker 
255*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" A");
256*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello A World", engine()->GetText().c_str());
257*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L'W', engine()->GetChar(8));
258*3ac0a46fSAndroid Build Coastguard Worker 
259*3ac0a46fSAndroid Build Coastguard Worker   engine()->EnablePasswordMode(true);
260*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L'*', engine()->GetChar(8));
261*3ac0a46fSAndroid Build Coastguard Worker 
262*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetAliasChar(L'+');
263*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(L'+', engine()->GetChar(8));
264*3ac0a46fSAndroid Build Coastguard Worker }
265*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetWidthOfChar)266*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetWidthOfChar) {
267*3ac0a46fSAndroid Build Coastguard Worker   // Out of Bounds.
268*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0, engine()->GetWidthOfChar(0));
269*3ac0a46fSAndroid Build Coastguard Worker 
270*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
271*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(173280, engine()->GetWidthOfChar(0));
272*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(133440, engine()->GetWidthOfChar(1));
273*3ac0a46fSAndroid Build Coastguard Worker 
274*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"\t");
275*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0, engine()->GetWidthOfChar(0));
276*3ac0a46fSAndroid Build Coastguard Worker }
277*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetDisplayPos)278*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetDisplayPos) {
279*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetDisplayPos(FDE_TEXTEDITPIECE()).size());
280*3ac0a46fSAndroid Build Coastguard Worker }
281*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,Selection)282*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, Selection) {
283*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
284*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
285*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
286*3ac0a46fSAndroid Build Coastguard Worker 
287*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
288*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->DeleteSelectedText().c_str());
289*3ac0a46fSAndroid Build Coastguard Worker 
290*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
291*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
292*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->HasSelection());
293*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetSelectedText().c_str());
294*3ac0a46fSAndroid Build Coastguard Worker 
295*3ac0a46fSAndroid Build Coastguard Worker   engine()->ClearSelection();
296*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
297*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetSelectedText().c_str());
298*3ac0a46fSAndroid Build Coastguard Worker 
299*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
300*3ac0a46fSAndroid Build Coastguard Worker   size_t start_idx;
301*3ac0a46fSAndroid Build Coastguard Worker   size_t count;
302*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->GetSelection();
303*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
304*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(11U, count);
305*3ac0a46fSAndroid Build Coastguard Worker 
306*3ac0a46fSAndroid Build Coastguard Worker   // Selection before gap.
307*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetSelectedText().c_str());
308*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->HasSelection());
309*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
310*3ac0a46fSAndroid Build Coastguard Worker 
311*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" A");
312*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
313*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetSelectedText().c_str());
314*3ac0a46fSAndroid Build Coastguard Worker 
315*3ac0a46fSAndroid Build Coastguard Worker   // Selection over the gap.
316*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
317*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->HasSelection());
318*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello A World", engine()->GetSelectedText().c_str());
319*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
320*3ac0a46fSAndroid Build Coastguard Worker 
321*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
322*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
323*3ac0a46fSAndroid Build Coastguard Worker 
324*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->DeleteSelectedText().c_str());
325*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
326*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
327*3ac0a46fSAndroid Build Coastguard Worker 
328*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
329*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(5, 5);
330*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L" Worl", engine()->DeleteSelectedText().c_str());
331*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
332*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hellod", engine()->GetText().c_str());
333*3ac0a46fSAndroid Build Coastguard Worker 
334*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
335*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
336*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
337*3ac0a46fSAndroid Build Coastguard Worker   engine()->ReplaceSelectedText(L"Goodbye Everybody");
338*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
339*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Goodbye Everybody", engine()->GetText().c_str());
340*3ac0a46fSAndroid Build Coastguard Worker 
341*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
342*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
343*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(1, 4);
344*3ac0a46fSAndroid Build Coastguard Worker   engine()->ReplaceSelectedText(L"i,");
345*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->HasSelection());
346*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hi, World", engine()->GetText().c_str());
347*3ac0a46fSAndroid Build Coastguard Worker 
348*3ac0a46fSAndroid Build Coastguard Worker   // Selection fully after gap.
349*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
350*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
351*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"A ");
352*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(3, 6);
353*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"ello", engine()->GetSelectedText().c_str());
354*3ac0a46fSAndroid Build Coastguard Worker 
355*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
356*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
357*3ac0a46fSAndroid Build Coastguard Worker   engine()->ClearSelection();
358*3ac0a46fSAndroid Build Coastguard Worker   engine()->DeleteSelectedText();
359*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
360*3ac0a46fSAndroid Build Coastguard Worker }
361*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,UndoRedo)362*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, UndoRedo) {
363*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanUndo());
364*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanRedo());
365*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->Undo());
366*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->Redo());
367*3ac0a46fSAndroid Build Coastguard Worker 
368*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
369*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
370*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanRedo());
371*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
372*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
373*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanUndo());
374*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanRedo());
375*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Redo());
376*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
377*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
378*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanRedo());
379*3ac0a46fSAndroid Build Coastguard Worker 
380*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
381*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanUndo());
382*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanRedo());
383*3ac0a46fSAndroid Build Coastguard Worker 
384*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
385*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
386*3ac0a46fSAndroid Build Coastguard Worker   engine()->DeleteSelectedText();
387*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
388*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
389*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
390*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
391*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanRedo());
392*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Redo());
393*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetText().c_str());
394*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
395*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanRedo());
396*3ac0a46fSAndroid Build Coastguard Worker 
397*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
398*3ac0a46fSAndroid Build Coastguard Worker   engine()->SelectAll();
399*3ac0a46fSAndroid Build Coastguard Worker   engine()->ReplaceSelectedText(L"Goodbye Friend");
400*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Goodbye Friend", engine()->GetText().c_str());
401*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
402*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
403*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
404*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanRedo());
405*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Redo());
406*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Goodbye Friend", engine()->GetText().c_str());
407*3ac0a46fSAndroid Build Coastguard Worker 
408*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
409*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetMaxEditOperationsForTesting(3);
410*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"First ");
411*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(engine()->GetLength(), L"Second ");
412*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(engine()->GetLength(), L"Third");
413*3ac0a46fSAndroid Build Coastguard Worker 
414*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
415*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
416*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"First Second ", engine()->GetText().c_str());
417*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanUndo());
418*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
419*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(
420*3ac0a46fSAndroid Build Coastguard Worker       engine()->CanUndo());  // Can't undo First; undo buffer too small.
421*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"First ", engine()->GetText().c_str());
422*3ac0a46fSAndroid Build Coastguard Worker 
423*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanRedo());
424*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Redo());
425*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanRedo());
426*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Redo());
427*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanRedo());
428*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"First Second Third", engine()->GetText().c_str());
429*3ac0a46fSAndroid Build Coastguard Worker 
430*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
431*3ac0a46fSAndroid Build Coastguard Worker 
432*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetMaxEditOperationsForTesting(4);
433*3ac0a46fSAndroid Build Coastguard Worker 
434*3ac0a46fSAndroid Build Coastguard Worker   // Go beyond the max operations limit.
435*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"H");
436*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(1, L"e");
437*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(2, L"l");
438*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(3, L"l");
439*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(4, L"o");
440*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(5, L" World");
441*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
442*3ac0a46fSAndroid Build Coastguard Worker 
443*3ac0a46fSAndroid Build Coastguard Worker   // Do A, undo. Do B, undo. Redo should cause B.
444*3ac0a46fSAndroid Build Coastguard Worker   engine()->Delete(4, 3);
445*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hellorld", engine()->GetText().c_str());
446*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
447*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
448*3ac0a46fSAndroid Build Coastguard Worker   engine()->Delete(5, 6);
449*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
450*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
451*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
452*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Redo());
453*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
454*3ac0a46fSAndroid Build Coastguard Worker 
455*3ac0a46fSAndroid Build Coastguard Worker   // Undo down to the limit.
456*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
457*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello World", engine()->GetText().c_str());
458*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
459*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetText().c_str());
460*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->Undo());
461*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hell", engine()->GetText().c_str());
462*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->Undo());
463*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hell", engine()->GetText().c_str());
464*3ac0a46fSAndroid Build Coastguard Worker }
465*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetIndexForPoint)466*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetIndexForPoint) {
467*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetFontSize(10.0f);
468*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
469*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetIndexForPoint({0.0f, 0.0f}));
470*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(11U, engine()->GetIndexForPoint({999999.0f, 9999999.0f}));
471*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(11U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
472*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, engine()->GetIndexForPoint({5.0f, 5.0f}));
473*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, engine()->GetIndexForPoint({10.0f, 5.0f}));
474*3ac0a46fSAndroid Build Coastguard Worker }
475*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetIndexForPointLineWrap)476*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetIndexForPointLineWrap) {
477*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetFontSize(10.0f);
478*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0,
479*3ac0a46fSAndroid Build Coastguard Worker                    L"A text long enough to span multiple lines and test "
480*3ac0a46fSAndroid Build Coastguard Worker                    L"getting indexes on multi-line edits.");
481*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetIndexForPoint({0.0f, 0.0f}));
482*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(87U, engine()->GetIndexForPoint({999999.0f, 9999999.0f}));
483*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(18U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
484*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(19U, engine()->GetIndexForPoint({1.0f, 10.0f}));
485*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, engine()->GetIndexForPoint({5.0f, 5.0f}));
486*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, engine()->GetIndexForPoint({10.0f, 5.0f}));
487*3ac0a46fSAndroid Build Coastguard Worker }
488*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetIndexForPointSpaceAtEnd)489*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetIndexForPointSpaceAtEnd) {
490*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetFontSize(10.0f);
491*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World ");
492*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetIndexForPoint({0.0f, 0.0f}));
493*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(12U, engine()->GetIndexForPoint({999999.0f, 9999999.0f}));
494*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(12U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
495*3ac0a46fSAndroid Build Coastguard Worker }
496*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetIndexForPointLineBreaks)497*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetIndexForPointLineBreaks) {
498*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetFontSize(10.0f);
499*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello\nWorld");
500*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetIndexForPoint({0.0f, 0.0f}));
501*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, engine()->GetIndexForPoint({999999.0f, 0.0f}));
502*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(6U, engine()->GetIndexForPoint({0.0f, 10.0f}));
503*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(11U, engine()->GetIndexForPoint({999999.0f, 9999999.0f}));
504*3ac0a46fSAndroid Build Coastguard Worker }
505*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,CanGenerateCharacterInfo)506*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, CanGenerateCharacterInfo) {
507*3ac0a46fSAndroid Build Coastguard Worker   RetainPtr<CFGAS_GEFont> font = engine()->GetFont();
508*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_TRUE(font);
509*3ac0a46fSAndroid Build Coastguard Worker 
510*3ac0a46fSAndroid Build Coastguard Worker   // Has font but no text.
511*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanGenerateCharacterInfo());
512*3ac0a46fSAndroid Build Coastguard Worker 
513*3ac0a46fSAndroid Build Coastguard Worker   // Has font and text.
514*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hi!");
515*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(engine()->CanGenerateCharacterInfo());
516*3ac0a46fSAndroid Build Coastguard Worker 
517*3ac0a46fSAndroid Build Coastguard Worker   // Has text but no font.
518*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetFont(nullptr);
519*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanGenerateCharacterInfo());
520*3ac0a46fSAndroid Build Coastguard Worker 
521*3ac0a46fSAndroid Build Coastguard Worker   // Has no text and no font.
522*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
523*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(engine()->CanGenerateCharacterInfo());
524*3ac0a46fSAndroid Build Coastguard Worker }
525*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,GetCharacterInfo)526*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, GetCharacterInfo) {
527*3ac0a46fSAndroid Build Coastguard Worker   std::pair<int32_t, CFX_RectF> char_info;
528*3ac0a46fSAndroid Build Coastguard Worker 
529*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hi!");
530*3ac0a46fSAndroid Build Coastguard Worker   ASSERT_EQ(3U, engine()->GetLength());
531*3ac0a46fSAndroid Build Coastguard Worker 
532*3ac0a46fSAndroid Build Coastguard Worker   char_info = engine()->GetCharacterInfo(0);
533*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0, char_info.first);
534*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(0.0f, char_info.second.Left());
535*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
536*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(8.664f, char_info.second.Width());
537*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
538*3ac0a46fSAndroid Build Coastguard Worker 
539*3ac0a46fSAndroid Build Coastguard Worker   char_info = engine()->GetCharacterInfo(1);
540*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0, char_info.first);
541*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(8.664f, char_info.second.Left());
542*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
543*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(3.324f, char_info.second.Width());
544*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
545*3ac0a46fSAndroid Build Coastguard Worker 
546*3ac0a46fSAndroid Build Coastguard Worker   char_info = engine()->GetCharacterInfo(2);
547*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0, char_info.first);
548*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(11.988f, char_info.second.Left());
549*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
550*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(3.996f, char_info.second.Width());
551*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
552*3ac0a46fSAndroid Build Coastguard Worker 
553*3ac0a46fSAndroid Build Coastguard Worker   // Allow retrieving the character info for the end of the text, as that
554*3ac0a46fSAndroid Build Coastguard Worker   // information can be used to determine where to draw a cursor positioned at
555*3ac0a46fSAndroid Build Coastguard Worker   // the end.
556*3ac0a46fSAndroid Build Coastguard Worker   char_info = engine()->GetCharacterInfo(3);
557*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0, char_info.first);
558*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(15.984, char_info.second.Left());
559*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(0.0f, char_info.second.Top());
560*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(0.0f, char_info.second.Width());
561*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FLOAT_EQ(12.0f, char_info.second.Height());
562*3ac0a46fSAndroid Build Coastguard Worker }
563*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,BoundsForWordAt)564*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, BoundsForWordAt) {
565*3ac0a46fSAndroid Build Coastguard Worker   size_t start_idx;
566*3ac0a46fSAndroid Build Coastguard Worker   size_t count;
567*3ac0a46fSAndroid Build Coastguard Worker 
568*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(100);
569*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
570*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, count);
571*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
572*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetSelectedText().c_str());
573*3ac0a46fSAndroid Build Coastguard Worker 
574*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
575*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
576*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(0);
577*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
578*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, count);
579*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
580*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetSelectedText().c_str());
581*3ac0a46fSAndroid Build Coastguard Worker 
582*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
583*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello World");
584*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(100);
585*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
586*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, count);
587*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
588*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"", engine()->GetSelectedText().c_str());
589*3ac0a46fSAndroid Build Coastguard Worker 
590*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(0);
591*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
592*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, count);
593*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
594*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetSelectedText().c_str());
595*3ac0a46fSAndroid Build Coastguard Worker 
596*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(1);
597*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
598*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, count);
599*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
600*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetSelectedText().c_str());
601*3ac0a46fSAndroid Build Coastguard Worker 
602*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(4);
603*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, start_idx);
604*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, count);
605*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
606*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"Hello", engine()->GetSelectedText().c_str());
607*3ac0a46fSAndroid Build Coastguard Worker 
608*3ac0a46fSAndroid Build Coastguard Worker   // Select the space
609*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(5);
610*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, start_idx);
611*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, count);
612*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
613*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L" ", engine()->GetSelectedText().c_str());
614*3ac0a46fSAndroid Build Coastguard Worker 
615*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(6);
616*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(6U, start_idx);
617*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, count);
618*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
619*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
620*3ac0a46fSAndroid Build Coastguard Worker 
621*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
622*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"123 456 789");
623*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(5);
624*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
625*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"456", engine()->GetSelectedText().c_str());
626*3ac0a46fSAndroid Build Coastguard Worker 
627*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
628*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"123def789");
629*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(5);
630*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
631*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"123def789", engine()->GetSelectedText().c_str());
632*3ac0a46fSAndroid Build Coastguard Worker 
633*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
634*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"abc456ghi");
635*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(5);
636*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
637*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"abc456ghi", engine()->GetSelectedText().c_str());
638*3ac0a46fSAndroid Build Coastguard Worker 
639*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
640*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"hello, world");
641*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(0);
642*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
643*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"hello", engine()->GetSelectedText().c_str());
644*3ac0a46fSAndroid Build Coastguard Worker 
645*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
646*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"hello, world");
647*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(5);
648*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
649*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L",", engine()->GetSelectedText().c_str());
650*3ac0a46fSAndroid Build Coastguard Worker 
651*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
652*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"np-complete");
653*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(6);
654*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
655*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"complete", engine()->GetSelectedText().c_str());
656*3ac0a46fSAndroid Build Coastguard Worker 
657*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
658*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"(123) 456-7890");
659*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(0);
660*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
661*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"(", engine()->GetSelectedText().c_str());
662*3ac0a46fSAndroid Build Coastguard Worker 
663*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(1);
664*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
665*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"123", engine()->GetSelectedText().c_str());
666*3ac0a46fSAndroid Build Coastguard Worker 
667*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(7);
668*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
669*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"456", engine()->GetSelectedText().c_str());
670*3ac0a46fSAndroid Build Coastguard Worker 
671*3ac0a46fSAndroid Build Coastguard Worker   std::tie(start_idx, count) = engine()->BoundsForWordAt(11);
672*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, count);
673*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"7890", engine()->GetSelectedText().c_str());
674*3ac0a46fSAndroid Build Coastguard Worker 
675*3ac0a46fSAndroid Build Coastguard Worker   // Tests from:
676*3ac0a46fSAndroid Build Coastguard Worker   // http://unicode.org/Public/UNIDATA/auxiliary/WordBreakTest.html#samples
677*3ac0a46fSAndroid Build Coastguard Worker   struct bounds {
678*3ac0a46fSAndroid Build Coastguard Worker     size_t start;
679*3ac0a46fSAndroid Build Coastguard Worker     size_t end;
680*3ac0a46fSAndroid Build Coastguard Worker   };
681*3ac0a46fSAndroid Build Coastguard Worker   struct {
682*3ac0a46fSAndroid Build Coastguard Worker     const wchar_t* str;
683*3ac0a46fSAndroid Build Coastguard Worker     std::vector<const wchar_t*> results;
684*3ac0a46fSAndroid Build Coastguard Worker   } tests[] = {
685*3ac0a46fSAndroid Build Coastguard Worker       // {L"\r\na\n\u0308", {L"\r\n", L"a", L"\n", L"\u0308"}},
686*3ac0a46fSAndroid Build Coastguard Worker       // {L"a\u0308", {L"a\u0308"}},
687*3ac0a46fSAndroid Build Coastguard Worker       // {L" \u200d\u0646", {L" \u200d", L"\u0646"}},
688*3ac0a46fSAndroid Build Coastguard Worker       // {L"\u0646\u200d ", {L"\u0646\u200d", L" "}},
689*3ac0a46fSAndroid Build Coastguard Worker       {L"AAA", {L"AAA"}},
690*3ac0a46fSAndroid Build Coastguard Worker       {L"A:A", {L"A:A"}},
691*3ac0a46fSAndroid Build Coastguard Worker       {L"A::A", {L"A", L":", L":", L"A"}},
692*3ac0a46fSAndroid Build Coastguard Worker       // {L"\u05d0'", {L"\u05d0'"}},
693*3ac0a46fSAndroid Build Coastguard Worker       // {L"\u05d0\"\u05d0", {L"\u05d0\"\u05d0"}},
694*3ac0a46fSAndroid Build Coastguard Worker       {L"A00A", {L"A00A"}},
695*3ac0a46fSAndroid Build Coastguard Worker       {L"0,0", {L"0,0"}},
696*3ac0a46fSAndroid Build Coastguard Worker       {L"0,,0", {L"0", L",", L",", L"0"}},
697*3ac0a46fSAndroid Build Coastguard Worker       {L"\u3031\u3031", {L"\u3031\u3031"}},
698*3ac0a46fSAndroid Build Coastguard Worker       {L"A_0_\u3031_", {L"A_0_\u3031_"}},
699*3ac0a46fSAndroid Build Coastguard Worker       {L"A__A", {L"A__A"}},
700*3ac0a46fSAndroid Build Coastguard Worker       // {L"\u200d\u2640", {L"\u200d\u2640"}},
701*3ac0a46fSAndroid Build Coastguard Worker       // {L"a\u0308\u200b\u0308b", {L"a\u0308\u200b\u0308b"}},
702*3ac0a46fSAndroid Build Coastguard Worker   };
703*3ac0a46fSAndroid Build Coastguard Worker 
704*3ac0a46fSAndroid Build Coastguard Worker   for (auto t : tests) {
705*3ac0a46fSAndroid Build Coastguard Worker     engine()->Clear();
706*3ac0a46fSAndroid Build Coastguard Worker     engine()->Insert(0, t.str);
707*3ac0a46fSAndroid Build Coastguard Worker 
708*3ac0a46fSAndroid Build Coastguard Worker     size_t idx = 0;
709*3ac0a46fSAndroid Build Coastguard Worker     for (const auto* res : t.results) {
710*3ac0a46fSAndroid Build Coastguard Worker       std::tie(start_idx, count) = engine()->BoundsForWordAt(idx);
711*3ac0a46fSAndroid Build Coastguard Worker       engine()->SetSelection(start_idx, count);
712*3ac0a46fSAndroid Build Coastguard Worker       EXPECT_STREQ(res, engine()->GetSelectedText().c_str())
713*3ac0a46fSAndroid Build Coastguard Worker           << "Input: '" << t.str << "'";
714*3ac0a46fSAndroid Build Coastguard Worker       idx += count;
715*3ac0a46fSAndroid Build Coastguard Worker     }
716*3ac0a46fSAndroid Build Coastguard Worker   }
717*3ac0a46fSAndroid Build Coastguard Worker }
718*3ac0a46fSAndroid Build Coastguard Worker 
TEST_F(CFDE_TextEditEngineTest,CursorMovement)719*3ac0a46fSAndroid Build Coastguard Worker TEST_F(CFDE_TextEditEngineTest, CursorMovement) {
720*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
721*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello");
722*3ac0a46fSAndroid Build Coastguard Worker 
723*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetIndexLeft(0));
724*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, engine()->GetIndexRight(5));
725*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, engine()->GetIndexUp(2));
726*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, engine()->GetIndexDown(2));
727*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(1U, engine()->GetIndexLeft(2));
728*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(3U, engine()->GetIndexRight(2));
729*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(0U, engine()->GetIndexAtStartOfLine(2));
730*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(5U, engine()->GetIndexAtEndOfLine(2));
731*3ac0a46fSAndroid Build Coastguard Worker 
732*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
733*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"The book is \"مدخل إلى C++\"");
734*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FX_IsOdd(engine()->GetCharacterInfo(3).first));
735*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(2U, engine()->GetIndexLeft(3));
736*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(4U, engine()->GetIndexRight(3));
737*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_TRUE(FX_IsOdd(engine()->GetCharacterInfo(15).first));
738*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(14U, engine()->GetIndexLeft(15));
739*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(16U, engine()->GetIndexRight(15));
740*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_FALSE(FX_IsOdd(engine()->GetCharacterInfo(23).first));
741*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(22U, engine()->GetIndexLeft(23));
742*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(24U, engine()->GetIndexRight(23));
743*3ac0a46fSAndroid Build Coastguard Worker 
744*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
745*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello\r\nWorld\r\nTest");
746*3ac0a46fSAndroid Build Coastguard Worker   // Move to end of Hello from start of World.
747*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexLeft(7U), 7);
748*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"\r\nWorld", engine()->GetSelectedText().c_str());
749*3ac0a46fSAndroid Build Coastguard Worker 
750*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in Hello from second letter in World.
751*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(8U), 2);
752*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"el", engine()->GetSelectedText().c_str());
753*3ac0a46fSAndroid Build Coastguard Worker 
754*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in World from second letter in Test.
755*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(15U), 2);
756*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"or", engine()->GetSelectedText().c_str());
757*3ac0a46fSAndroid Build Coastguard Worker 
758*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in World from second letter in Hello.
759*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexDown(1U), 2);
760*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"or", engine()->GetSelectedText().c_str());
761*3ac0a46fSAndroid Build Coastguard Worker 
762*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in Test from second letter in World.
763*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexDown(8U), 2);
764*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"es", engine()->GetSelectedText().c_str());
765*3ac0a46fSAndroid Build Coastguard Worker 
766*3ac0a46fSAndroid Build Coastguard Worker   size_t start_idx = engine()->GetIndexAtStartOfLine(8U);
767*3ac0a46fSAndroid Build Coastguard Worker   size_t end_idx = engine()->GetIndexAtEndOfLine(8U);
768*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, end_idx - start_idx);
769*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
770*3ac0a46fSAndroid Build Coastguard Worker 
771*3ac0a46fSAndroid Build Coastguard Worker   // Move past \r\n to before W.
772*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexRight(5U), 5);
773*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
774*3ac0a46fSAndroid Build Coastguard Worker 
775*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
776*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Short\nAnd a very long line");
777*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(14U), 11);
778*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"\nAnd a very", engine()->GetSelectedText().c_str());
779*3ac0a46fSAndroid Build Coastguard Worker 
780*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
781*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"A Very long line\nShort");
782*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_EQ(engine()->GetLength(), engine()->GetIndexDown(8U));
783*3ac0a46fSAndroid Build Coastguard Worker 
784*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
785*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello\rWorld\rTest");
786*3ac0a46fSAndroid Build Coastguard Worker   // Move to end of Hello from start of World.
787*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexLeft(6U), 6);
788*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"\rWorld", engine()->GetSelectedText().c_str());
789*3ac0a46fSAndroid Build Coastguard Worker 
790*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in Hello from second letter in World.
791*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(7U), 2);
792*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"el", engine()->GetSelectedText().c_str());
793*3ac0a46fSAndroid Build Coastguard Worker 
794*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in World from second letter in Test.
795*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(13U), 2);
796*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"or", engine()->GetSelectedText().c_str());
797*3ac0a46fSAndroid Build Coastguard Worker 
798*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in World from second letter in Hello.
799*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexDown(1U), 2);
800*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"or", engine()->GetSelectedText().c_str());
801*3ac0a46fSAndroid Build Coastguard Worker 
802*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in Test from second letter in World.
803*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexDown(7U), 2);
804*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"es", engine()->GetSelectedText().c_str());
805*3ac0a46fSAndroid Build Coastguard Worker 
806*3ac0a46fSAndroid Build Coastguard Worker   start_idx = engine()->GetIndexAtStartOfLine(7U);
807*3ac0a46fSAndroid Build Coastguard Worker   end_idx = engine()->GetIndexAtEndOfLine(7U);
808*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, end_idx - start_idx);
809*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
810*3ac0a46fSAndroid Build Coastguard Worker 
811*3ac0a46fSAndroid Build Coastguard Worker   // Move past \r to before W.
812*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexRight(5U), 5);
813*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
814*3ac0a46fSAndroid Build Coastguard Worker 
815*3ac0a46fSAndroid Build Coastguard Worker   engine()->Clear();
816*3ac0a46fSAndroid Build Coastguard Worker   engine()->Insert(0, L"Hello\nWorld\nTest");
817*3ac0a46fSAndroid Build Coastguard Worker   // Move to end of Hello from start of World.
818*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexLeft(6U), 6);
819*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"\nWorld", engine()->GetSelectedText().c_str());
820*3ac0a46fSAndroid Build Coastguard Worker 
821*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in Hello from second letter in World.
822*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(7U), 2);
823*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"el", engine()->GetSelectedText().c_str());
824*3ac0a46fSAndroid Build Coastguard Worker 
825*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in World from second letter in Test.
826*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexUp(13U), 2);
827*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"or", engine()->GetSelectedText().c_str());
828*3ac0a46fSAndroid Build Coastguard Worker 
829*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in World from second letter in Hello.
830*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexDown(1U), 2);
831*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"or", engine()->GetSelectedText().c_str());
832*3ac0a46fSAndroid Build Coastguard Worker 
833*3ac0a46fSAndroid Build Coastguard Worker   // Second letter in Test from second letter in World.
834*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexDown(7U), 2);
835*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"es", engine()->GetSelectedText().c_str());
836*3ac0a46fSAndroid Build Coastguard Worker 
837*3ac0a46fSAndroid Build Coastguard Worker   start_idx = engine()->GetIndexAtStartOfLine(7U);
838*3ac0a46fSAndroid Build Coastguard Worker   end_idx = engine()->GetIndexAtEndOfLine(7U);
839*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(start_idx, end_idx - start_idx);
840*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
841*3ac0a46fSAndroid Build Coastguard Worker 
842*3ac0a46fSAndroid Build Coastguard Worker   // Move past \r to before W.
843*3ac0a46fSAndroid Build Coastguard Worker   engine()->SetSelection(engine()->GetIndexRight(5U), 5);
844*3ac0a46fSAndroid Build Coastguard Worker   EXPECT_STREQ(L"World", engine()->GetSelectedText().c_str());
845*3ac0a46fSAndroid Build Coastguard Worker }
846