@@ -29,21 +29,47 @@ namespace
2929{
3030constexpr auto kSingleText = " Hello World" ;
3131constexpr auto kMultilineText = " Line 1\n Line 2\n Line 3" ;
32+
33+ File getTextEditorTestFontFile ()
34+ {
35+ return File (__FILE__)
36+ .getParentDirectory ()
37+ .getParentDirectory ()
38+ .getChildFile (" data" )
39+ .getChildFile (" fonts" )
40+ .getChildFile (" Linefont-VariableFont_wdth,wght.ttf" );
41+ }
3242} // namespace
3343
3444class TextEditorTests : public ::testing::Test
3545{
3646protected:
3747 void SetUp () override
3848 {
49+ oldTheme = ApplicationTheme::getGlobalTheme ();
50+
51+ theme = new ApplicationTheme ();
52+
53+ Font font;
54+ auto result = font.loadFromFile (getTextEditorTestFontFile ());
55+ ASSERT_TRUE (result.wasOk ());
56+
57+ theme->setDefaultFont (std::move (font));
58+ ApplicationTheme::setGlobalTheme (theme);
59+
3960 editor = std::make_unique<TextEditor> (" testEditor" );
4061 }
4162
4263 void TearDown () override
4364 {
4465 editor.reset ();
66+ ApplicationTheme::setGlobalTheme (oldTheme.get ());
67+ theme = nullptr ;
68+ oldTheme = nullptr ;
4569 }
4670
71+ ApplicationTheme::Ptr theme;
72+ ApplicationTheme::Ptr oldTheme;
4773 std::unique_ptr<TextEditor> editor;
4874};
4975
@@ -63,6 +89,13 @@ TEST_F (TextEditorTests, SetTextUpdatesContent)
6389 EXPECT_EQ (0 , editor->getCaretPosition ());
6490}
6591
92+ TEST_F (TextEditorTests, SetTextStripsCarriageReturns)
93+ {
94+ editor->setText (" Hello\r\n World\r " );
95+
96+ EXPECT_EQ (String (" Hello\n World" ), editor->getText ());
97+ }
98+
6699TEST_F (TextEditorTests, CaretPositionHandling)
67100{
68101 editor->setText (kSingleText );
@@ -106,6 +139,55 @@ TEST_F (TextEditorTests, TextInsertion)
106139 EXPECT_EQ (11 , editor->getCaretPosition ());
107140}
108141
142+ TEST_F (TextEditorTests, InsertTextNormalizesNewlinesInSingleLineMode)
143+ {
144+ editor->setText (" Hello" );
145+ editor->setCaretPosition (5 );
146+
147+ editor->insertText (" \r\n World" );
148+
149+ EXPECT_EQ (String (" Hello World" ), editor->getText ());
150+ EXPECT_EQ (11 , editor->getCaretPosition ());
151+ }
152+
153+ TEST_F (TextEditorTests, InsertTextReplacesSelectionWithSingleNotification)
154+ {
155+ editor->setText (" Hello brave world" , dontSendNotification);
156+ editor->setSelection (Range<int > (6 , 11 ));
157+
158+ int callCount = 0 ;
159+ editor->onTextChange = [&callCount]
160+ {
161+ ++callCount;
162+ };
163+
164+ editor->insertText (" small" , sendNotification);
165+
166+ EXPECT_EQ (String (" Hello small world" ), editor->getText ());
167+ EXPECT_EQ (11 , editor->getCaretPosition ());
168+ EXPECT_FALSE (editor->hasSelection ());
169+ EXPECT_EQ (1 , callCount);
170+ }
171+
172+ TEST_F (TextEditorTests, InsertTextReplacingSelectionHonorsDontSendNotification)
173+ {
174+ editor->setText (" abcdef" , dontSendNotification);
175+ editor->setSelection (Range<int > (1 , 5 ));
176+
177+ int callCount = 0 ;
178+ editor->onTextChange = [&callCount]
179+ {
180+ ++callCount;
181+ };
182+
183+ editor->insertText (" X" , dontSendNotification);
184+
185+ EXPECT_EQ (String (" aXf" ), editor->getText ());
186+ EXPECT_EQ (2 , editor->getCaretPosition ());
187+ EXPECT_FALSE (editor->hasSelection ());
188+ EXPECT_EQ (0 , callCount);
189+ }
190+
109191TEST_F (TextEditorTests, TextDeletion)
110192{
111193 editor->setText (kSingleText );
@@ -126,6 +208,19 @@ TEST_F (TextEditorTests, MultiLineMode)
126208 EXPECT_EQ (String (kMultilineText ), editor->getText ());
127209}
128210
211+ TEST_F (TextEditorTests, StyledTextWrapModeFollowsMultiLineMode)
212+ {
213+ editor->setBounds (0 .0f , 0 .0f , 200 .0f , 100 .0f );
214+ editor->setText (" A long enough line to exercise styled text setup" );
215+
216+ editor->getCaretBounds ();
217+ EXPECT_EQ (StyledText::noWrap, editor->getStyledText ().getWrap ());
218+
219+ editor->setMultiLine (true );
220+ editor->moveCaretDown ();
221+ EXPECT_EQ (StyledText::wrap, editor->getStyledText ().getWrap ());
222+ }
223+
129224TEST_F (TextEditorTests, ReadOnlyMode)
130225{
131226 editor->setText (kSingleText );
@@ -283,6 +378,38 @@ TEST_F (TextEditorTests, MoveCaretLeftRight)
283378 EXPECT_EQ (String (" o" ), editor->getSelectedText ());
284379}
285380
381+ TEST_F (TextEditorTests, MoveCaretToLineBoundariesInMultilineText)
382+ {
383+ editor->setMultiLine (true );
384+ editor->setText (" abc\n defg\n hi" );
385+ editor->setCaretPosition (6 );
386+
387+ editor->moveCaretToStartOfLine ();
388+ EXPECT_EQ (4 , editor->getCaretPosition ());
389+ EXPECT_FALSE (editor->hasSelection ());
390+
391+ editor->setCaretPosition (6 );
392+ editor->moveCaretToEndOfLine (true );
393+ EXPECT_EQ (8 , editor->getCaretPosition ());
394+ EXPECT_TRUE (editor->hasSelection ());
395+ EXPECT_EQ (String (" fg" ), editor->getSelectedText ());
396+ }
397+
398+ TEST_F (TextEditorTests, ControlArrowKeysMoveAcrossWords)
399+ {
400+ editor->setText (" Hello, brave world" );
401+ editor->setCaretPosition (7 );
402+
403+ editor->keyDown (KeyPress (KeyPress::rightKey, KeyModifiers (KeyModifiers::controlMask)), {});
404+ EXPECT_EQ (12 , editor->getCaretPosition ());
405+ EXPECT_FALSE (editor->hasSelection ());
406+
407+ editor->keyDown (KeyPress (KeyPress::leftKey, KeyModifiers (KeyModifiers::controlMask | KeyModifiers::shiftMask)), {});
408+ EXPECT_EQ (7 , editor->getCaretPosition ());
409+ EXPECT_TRUE (editor->hasSelection ());
410+ EXPECT_EQ (String (" brave" ), editor->getSelectedText ());
411+ }
412+
286413/* TODO: moveCaretToWordEnd/moveCaretToWordStart is private
287414TEST_F (TextEditorTests, WordNavigation)
288415{
0 commit comments