44import javafx .beans .property .SimpleIntegerProperty ;
55import javafx .scene .Scene ;
66import javafx .scene .control .Label ;
7+ import javafx .scene .input .KeyCode ;
78import javafx .stage .Stage ;
89import org .fxmisc .richtext .InlineCssTextAreaAppTest ;
910import org .fxmisc .richtext .RichTextFXTestBase ;
2425public class UndoManagerTests {
2526
2627 public class UsingInlineCssTextArea extends InlineCssTextAreaAppTest {
28+ private void checkCaretAtPosition (int position ) {
29+ checkSelection (position , position , position );
30+ }
31+
32+ private void checkSelection (int start , int end , int caret ) {
33+ assertEquals (start , area .getSelection ().getStart ());
34+ assertEquals (end , area .getSelection ().getEnd ());
35+ assertEquals (caret , area .getCaretPosition ());
36+ }
37+
38+ private void input (KeyCode ... codes ) {
39+ press (codes );
40+ release (codes );
41+ }
42+
43+ private void selectNext (int count ) {
44+ selectMultiple (count , KeyCode .RIGHT );
45+ }
46+
47+ private void selectPrevious (int count ) {
48+ selectMultiple (count , KeyCode .LEFT );
49+ }
50+
51+ private void selectMultiple (int count , KeyCode keyCode ) {
52+ press (KeyCode .SHIFT );
53+ for (int i = 0 ; i < count ; i ++) {
54+ input (keyCode );
55+ }
56+ release (KeyCode .SHIFT );
57+
58+ }
2759
2860 @ Test
2961 public void incoming_change_is_not_merged_after_period_of_user_inactivity () {
@@ -43,11 +75,163 @@ public void incoming_change_is_not_merged_after_period_of_user_inactivity() {
4375 assertEquals ("" , area .getText ());
4476 }
4577
78+ @ Test // Perform addition, backspace, delete, replace and check the caret position
79+ public void undo_for_addition () {
80+ // Addition
81+ write ("Hat" );
82+ assertEquals ("Hat" , area .getText ());
83+ checkCaretAtPosition (3 );
84+
85+ // Move caret to 1
86+ area .moveTo (1 );
87+ checkCaretAtPosition (1 );
88+
89+ // Add a letter
90+ write ("e" );
91+ assertEquals ("Heat" , area .getText ());
92+ checkCaretAtPosition (2 );
93+
94+ // Undo removes " a"
95+ interact (area ::undo );
96+ assertEquals ("Hat" , area .getText ());
97+ checkCaretAtPosition (1 );
98+ }
99+
100+ @ Test // Perform addition, backspace, delete, replace and check the caret position
101+ public void undo_for_delete () {
102+ // Addition
103+ write ("Hat" );
104+ assertEquals ("Hat" , area .getText ());
105+ checkCaretAtPosition (3 );
106+
107+ // Move caret to 1
108+ area .moveTo (1 );
109+ checkCaretAtPosition (1 );
110+
111+ // Delete
112+ input (KeyCode .DELETE );
113+ assertEquals ("Ht" ,area .getText ());
114+ checkCaretAtPosition (1 );
115+
116+ // Undo puts back the 'a'
117+ interact (area ::undo );
118+ assertEquals ("Hat" ,area .getText ());
119+ checkCaretAtPosition (2 ); // TODO Bug #1293: Correct value is 1 (but creating test to cover existing behaviour)
120+
121+ // Delete with "delete" starting from the start and going to the end
122+ area .moveTo (1 );
123+ selectNext (2 );
124+ checkSelection (1 , 3 , 3 );
125+ // Backspace deletes
126+ input (KeyCode .DELETE );
127+ assertEquals ("H" ,area .getText ());
128+ checkCaretAtPosition (1 );
129+ // undo should put back the content and move the caret at the end
130+ interact (area ::undo );
131+ assertEquals ("Hat" ,area .getText ());
132+ checkCaretAtPosition (3 ); // TODO Bug #1293: Correct value is: checkSelection(1, 3, 3);
133+
134+ // Delete with "delete" from the end and going to the start
135+ area .moveTo (3 );
136+ selectPrevious (2 );
137+ checkSelection (1 , 3 , 1 );
138+ // Backspace deletes
139+ input (KeyCode .DELETE );
140+ assertEquals ("H" ,area .getText ());
141+ checkCaretAtPosition (1 );
142+ // undo should put back the content and move the caret at the end
143+ interact (area ::undo );
144+ assertEquals ("Hat" ,area .getText ());
145+ checkCaretAtPosition (3 ); // TODO Bug #1293: Correct value is: checkSelection(1, 3, 1);
146+ }
147+
148+ @ Test // Perform addition, backspace, delete, replace and check the caret position
149+ public void undo_for_backspace () {
150+ // Addition
151+ write ("Hat" );
152+ assertEquals ("Hat" , area .getText ());
153+ checkCaretAtPosition (3 );
154+
155+ // Move caret to 1
156+ area .moveTo (1 );
157+ checkCaretAtPosition (1 );
158+
159+ // Backspace
160+ input (KeyCode .BACK_SPACE );
161+ assertEquals ("at" ,area .getText ());
162+ checkCaretAtPosition (0 );
163+
164+ // Undo puts back the a
165+ interact (area ::undo );
166+ assertEquals ("Hat" ,area .getText ());
167+ checkCaretAtPosition (1 );
168+
169+ // Delete with backspace starting from the start and going to the end
170+ selectNext (2 );
171+ checkSelection (1 , 3 , 3 );
172+ // Backspace deletes
173+ input (KeyCode .BACK_SPACE );
174+ assertEquals ("H" ,area .getText ());
175+ checkCaretAtPosition (1 );
176+ // undo should put back the content and move the caret at the end
177+ interact (area ::undo );
178+ assertEquals ("Hat" ,area .getText ());
179+ checkCaretAtPosition (3 ); // TODO Bug #1293: Correct value is: checkSelection(1, 3, 3)
180+
181+ // Delete with backspace from the end and going to the start
182+ area .moveTo (3 );
183+ selectPrevious (2 );
184+ checkSelection (1 , 3 , 1 );
185+ // Backspace deletes
186+ input (KeyCode .BACK_SPACE );
187+ assertEquals ("H" ,area .getText ());
188+ checkCaretAtPosition (1 );
189+ // undo should put back the content and move the caret at the end
190+ interact (area ::undo );
191+ assertEquals ("Hat" ,area .getText ());
192+ checkCaretAtPosition (3 ); // TODO Bug #1293: Correct value is: checkSelection(1, 3, 1)
193+ }
194+
195+ @ Test // Perform addition, backspace, delete, replace and check the caret position
196+ public void undo_for_replace () {
197+ // Addition
198+ write ("Heat" );
199+ assertEquals ("Heat" , area .getText ());
200+ checkCaretAtPosition (4 );
201+
202+ // Replace (but first add)
203+ area .selectRange (1 , 3 );
204+ checkSelection (1 , 3 , 3 );
205+ // press a key to replace the text
206+ input (KeyCode .I );
207+ assertEquals ("Hit" ,area .getText ());
208+ checkCaretAtPosition (2 );
209+ // undo should put back the content and move the caret at the end
210+ interact (area ::undo );
211+ assertEquals ("Heat" ,area .getText ());
212+ checkCaretAtPosition (3 ); // TODO Bug #1293: Correct value is: checkSelection(1, 3, 3);
213+
214+ // Now perform the same operation but the caret of the selection is at the start
215+ area .moveTo (3 );
216+ selectPrevious (2 );
217+ checkSelection (1 , 3 , 1 );
218+ // press a key to replace the text
219+ input (KeyCode .I );
220+ assertEquals ("Hit" ,area .getText ());
221+ checkCaretAtPosition (2 );
222+ // undo should put back the content and move the caret at the end
223+ interact (area ::undo );
224+ assertEquals ("Heat" ,area .getText ());
225+ checkCaretAtPosition (3 ); // TODO Bug #1293: Correct value is: checkSelection(1, 3, 1);
226+ }
227+
46228 @ Test // After undo, text insertion point jumps to the start of the text area #780
47229 // After undo, text insertion point jumps to the end of the text area #912
48230 public void undo_leaves_correct_insertion_point () {
49231
50232 write ("abc mno" );
233+ // ^
234+ assertEquals (7 , area .getCaretPosition ());
51235 interact (() -> {
52236 area .insertText (3 ," def" );
53237 area .appendText (" xyz" );
0 commit comments