1
+ /*******************************************************************************
2
+ * Copyright (c) 2024 Vector Informatik GmbH and others.
3
+ *
4
+ * This program and the accompanying materials
5
+ * are made available under the terms of the Eclipse Public License 2.0
6
+ * which accompanies this distribution, and is available at
7
+ * https://www.eclipse.org/legal/epl-2.0/
8
+ *
9
+ * SPDX-License-Identifier: EPL-2.0
10
+ *
11
+ * Contributors:
12
+ * Vector Informatik GmbH - initial API and implementation
13
+ *******************************************************************************/
14
+ package org .eclipse .ui .editors .tests ;
15
+
16
+ import static org .hamcrest .MatcherAssert .assertThat ;
17
+ import static org .hamcrest .Matchers .is ;
18
+ import static org .junit .Assert .assertEquals ;
19
+
20
+ import java .util .ResourceBundle ;
21
+
22
+ import org .hamcrest .Matchers ;
23
+ import org .junit .After ;
24
+ import org .junit .Before ;
25
+ import org .junit .Test ;
26
+ import org .osgi .framework .FrameworkUtil ;
27
+
28
+ import org .eclipse .core .runtime .CoreException ;
29
+
30
+ import org .eclipse .core .resources .IFile ;
31
+ import org .eclipse .core .resources .IProject ;
32
+ import org .eclipse .core .resources .IResource ;
33
+ import org .eclipse .core .resources .ResourcesPlugin ;
34
+
35
+ import org .eclipse .jface .dialogs .IDialogSettings ;
36
+ import org .eclipse .jface .viewers .ISelectionProvider ;
37
+
38
+ import org .eclipse .jface .text .Document ;
39
+ import org .eclipse .jface .text .TextSelection ;
40
+
41
+ import org .eclipse .ui .IEditorPart ;
42
+ import org .eclipse .ui .IWorkbench ;
43
+ import org .eclipse .ui .IWorkbenchPage ;
44
+ import org .eclipse .ui .IWorkbenchPartSite ;
45
+ import org .eclipse .ui .PartInitException ;
46
+ import org .eclipse .ui .PlatformUI ;
47
+ import org .eclipse .ui .ide .IDE ;
48
+ import org .eclipse .ui .internal .findandreplace .HistoryStore ;
49
+
50
+ import org .eclipse .ui .texteditor .AbstractTextEditor ;
51
+ import org .eclipse .ui .texteditor .FindNextAction ;
52
+ import org .eclipse .ui .texteditor .FindReplaceAction ;
53
+
54
+ public class FindNextActionTest {
55
+ private static final String TEST_PROJECT_NAME = "TestProject" ;
56
+
57
+ private static final String BUNDLE_FOR_CONSTRUCTED_KEYS_NAME = "org.eclipse.ui.texteditor.ConstructedEditorMessages" ;//$NON-NLS-1$
58
+
59
+ private static ResourceBundle bundleForConstructedKeys = ResourceBundle .getBundle (BUNDLE_FOR_CONSTRUCTED_KEYS_NAME );
60
+
61
+ private AbstractTextEditor editor ;
62
+
63
+ private IProject project ;
64
+
65
+ private FindNextAction action ;
66
+
67
+ private static enum Direction {
68
+ FORWARD , BACKWARD
69
+ }
70
+
71
+ @ Before
72
+ public void createTestProject () throws CoreException {
73
+ project = ResourcesPlugin .getWorkspace ().getRoot ().getProject (TEST_PROJECT_NAME );
74
+ project .create (null );
75
+ project .open (null );
76
+ }
77
+
78
+ public void openEditorAndFindNextAction (String content , Direction direction ) throws CoreException {
79
+ IFile file = createTestFile (content );
80
+ editor = openEditor (file );
81
+ action = new FindNextAction (bundleForConstructedKeys , "findNext" , editor , direction == Direction .FORWARD );
82
+ }
83
+
84
+ private IFile createTestFile (String content ) throws CoreException {
85
+ IFile file = project .getFile ("file.txt" );
86
+ file .create (content .getBytes (), IResource .FORCE , null );
87
+ file .setCharset (null , null );
88
+ return file ;
89
+ }
90
+
91
+ private static AbstractTextEditor openEditor (IFile file ) throws PartInitException {
92
+ IWorkbench workbench = PlatformUI .getWorkbench ();
93
+ IWorkbenchPage page = workbench .getActiveWorkbenchWindow ().getActivePage ();
94
+ IEditorPart editorPart = IDE .openEditor (page , file );
95
+ assertThat (editorPart , Matchers .instanceOf (AbstractTextEditor .class ));
96
+ return (AbstractTextEditor ) editorPart ;
97
+ }
98
+
99
+ @ After
100
+ public void tearDown () throws Exception {
101
+ resetInitialSearchSettings ();
102
+ closeEditor (editor );
103
+ editor = null ;
104
+ project .delete (true , null );
105
+ project = null ;
106
+ TestUtil .cleanUp ();
107
+ }
108
+
109
+ private void resetInitialSearchSettings () {
110
+ IDialogSettings settings = getActionSettings ();
111
+ settings .put ("isRegEx" , false );
112
+ settings .put ("casesensitive" , false );
113
+ settings .put ("wrap" , true );
114
+ settings .put ("wholeword" , false );
115
+ }
116
+
117
+ private static void closeEditor (IEditorPart editor ) {
118
+ IWorkbenchPartSite site ;
119
+ IWorkbenchPage page ;
120
+ if (editor != null && (site = editor .getSite ()) != null && (page = site .getPage ()) != null ) {
121
+ page .closeEditor (editor , false );
122
+ }
123
+ }
124
+
125
+ private void setEditorSelection (int offset , int length ) {
126
+ Document document = (Document ) editor .getDocumentProvider ().getDocument (editor .getEditorInput ());
127
+ TextSelection selection = new TextSelection (document , offset , length );
128
+ ISelectionProvider selectionProvider = editor .getSelectionProvider ();
129
+ selectionProvider .setSelection (selection );
130
+ }
131
+
132
+ private void assertSelectionIs (int offset , int length ) {
133
+ assertEquals (offset , getEditorSelection ().getRegions ()[0 ].getOffset ());
134
+ assertEquals (length , getEditorSelection ().getRegions ()[0 ].getLength ());
135
+ }
136
+
137
+ private TextSelection getEditorSelection () {
138
+ ISelectionProvider selectionProvider = editor .getSelectionProvider ();
139
+ if (selectionProvider .getSelection () instanceof TextSelection ) {
140
+ return (TextSelection ) selectionProvider .getSelection ();
141
+ }
142
+ return null ;
143
+ }
144
+
145
+ private IDialogSettings getActionSettings () {
146
+ IDialogSettings settings = PlatformUI .getDialogSettingsProvider (FrameworkUtil .getBundle (FindNextAction .class ))
147
+ .getDialogSettings ();
148
+ IDialogSettings fDialogSettings = settings .getSection (FindReplaceAction .class .getClass ().getName ());
149
+ if (fDialogSettings == null )
150
+ fDialogSettings = settings .addNewSection (FindReplaceAction .class .getClass ().getName ());
151
+ return fDialogSettings ;
152
+ }
153
+
154
+ @ Test
155
+ public void testFindNextForward () throws CoreException {
156
+ openEditorAndFindNextAction ("testtesttest" , Direction .FORWARD );
157
+ setEditorSelection (0 , 4 );
158
+ action .run ();
159
+ assertSelectionIs (4 , 4 );
160
+ action .run ();
161
+ assertSelectionIs (8 , 4 );
162
+ action .run ();
163
+ assertSelectionIs (0 , 4 );
164
+ }
165
+
166
+ @ Test
167
+ public void testFindNextBackwards () throws CoreException {
168
+ openEditorAndFindNextAction ("testtesttest" , Direction .BACKWARD );
169
+ setEditorSelection (4 , 4 );
170
+ action .run ();
171
+ assertSelectionIs (0 , 4 );
172
+ action .run ();
173
+ assertSelectionIs (8 , 4 );
174
+ }
175
+
176
+ @ Test
177
+ public void testFindNextFromHistory () throws CoreException {
178
+ openEditorAndFindNextAction ("word-abcd-text" , Direction .FORWARD );
179
+ IDialogSettings settings = getActionSettings ();
180
+ HistoryStore historyStore = new HistoryStore (settings , "findhistory" , 15 );
181
+ historyStore .add ("abcd" );
182
+ setEditorSelection (0 , 0 );
183
+ action .run ();
184
+ assertSelectionIs (5 , 4 );
185
+ setEditorSelection (3 , 0 );
186
+ action .run ();
187
+ assertSelectionIs (5 , 4 );
188
+ }
189
+
190
+ @ Test
191
+ public void testFindNextStoresCorrectHistory () throws CoreException {
192
+ openEditorAndFindNextAction ("history" , Direction .FORWARD );
193
+ setEditorSelection (0 , "history" .length ());
194
+ action .run ();
195
+ IDialogSettings settings = getActionSettings ();
196
+ HistoryStore historyStore = new HistoryStore (settings , "findhistory" , 15 );
197
+ assertThat (historyStore .get (0 ), is ("history" ));
198
+ }
199
+
200
+ @ Test
201
+ public void testFindNextWithRegExEscapedCorrectly () throws CoreException {
202
+ openEditorAndFindNextAction ("wo+rd-woord" , Direction .FORWARD );
203
+ IDialogSettings settings = getActionSettings ();
204
+ setEditorSelection (0 , 5 );
205
+ settings .put ("isRegEx" , true );
206
+ action .run ();
207
+ assertSelectionIs (0 , 5 );
208
+ }
209
+
210
+ @ Test
211
+ public void testCaseSensitiveFindNext () throws CoreException {
212
+ openEditorAndFindNextAction ("wordWORD" , Direction .FORWARD );
213
+ IDialogSettings settings = getActionSettings ();
214
+ settings .put ("casesensitive" , true );
215
+ setEditorSelection (0 , 4 );
216
+ action .run ();
217
+ assertSelectionIs (0 , 4 );
218
+ }
219
+
220
+ @ Test
221
+ public void testFindNextMultilineSelection () throws CoreException {
222
+ openEditorAndFindNextAction ("line\n \r next\n \r next\r \n line" , Direction .FORWARD );
223
+ // we expect the search string to only contain the first line
224
+ setEditorSelection (0 , 10 );
225
+ action .run ();
226
+ assertSelectionIs (18 , 4 );
227
+ }
228
+
229
+ @ Test
230
+ public void testFindNextNoWrap () throws CoreException {
231
+ openEditorAndFindNextAction ("wordword" , Direction .FORWARD );
232
+ IDialogSettings settings = getActionSettings ();
233
+ settings .put ("wrap" , false );
234
+ setEditorSelection (0 , 4 );
235
+ action .run ();
236
+ assertSelectionIs (4 , 4 );
237
+ action .run ();
238
+ assertSelectionIs (4 , 4 );
239
+ }
240
+
241
+ @ Test
242
+ public void testFindWholeWords () throws CoreException {
243
+ openEditorAndFindNextAction ("word longerword word" , Direction .FORWARD );
244
+ IDialogSettings settings = getActionSettings ();
245
+ settings .put ("wholeword" , true );
246
+ setEditorSelection (0 , 4 );
247
+ action .run ();
248
+ assertSelectionIs (16 , 4 );
249
+ }
250
+
251
+ @ Test
252
+ public void testFindWholeWordsIsNotWord () throws CoreException {
253
+ openEditorAndFindNextAction ("w ord longerw ordinner w ord" , Direction .FORWARD );
254
+ IDialogSettings settings = getActionSettings ();
255
+ settings .put ("wholeword" , true );
256
+ setEditorSelection (0 , 5 );
257
+ action .run ();
258
+ assertSelectionIs (12 , 5 );
259
+ action .run ();
260
+ assertSelectionIs (23 , 5 );
261
+ }
262
+
263
+ }
0 commit comments