Line 0
Link Here
|
|
|
1 |
/* |
2 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
3 |
* |
4 |
* Copyright 2012 Oracle and/or its affiliates. All rights reserved. |
5 |
* |
6 |
* Oracle and Java are registered trademarks of Oracle and/or its affiliates. |
7 |
* Other names may be trademarks of their respective owners. |
8 |
* |
9 |
* The contents of this file are subject to the terms of either the GNU |
10 |
* General Public License Version 2 only ("GPL") or the Common |
11 |
* Development and Distribution License("CDDL") (collectively, the |
12 |
* "License"). You may not use this file except in compliance with the |
13 |
* License. You can obtain a copy of the License at |
14 |
* http://www.netbeans.org/cddl-gplv2.html |
15 |
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the |
16 |
* specific language governing permissions and limitations under the |
17 |
* License. When distributing the software, include this License Header |
18 |
* Notice in each file and include the License file at |
19 |
* nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this |
20 |
* particular file as subject to the "Classpath" exception as provided |
21 |
* by Oracle in the GPL Version 2 section of the License file that |
22 |
* accompanied this code. If applicable, add the following below the |
23 |
* License Header, with the fields enclosed by brackets [] replaced by |
24 |
* your own identifying information: |
25 |
* "Portions Copyrighted [year] [name of copyright owner]" |
26 |
* |
27 |
* If you wish your version of this file to be governed by only the CDDL |
28 |
* or only the GPL Version 2, indicate your decision by adding |
29 |
* "[Contributor] elects to include this software in this distribution |
30 |
* under the [CDDL or GPL Version 2] license." If you do not indicate a |
31 |
* single choice of license, a recipient has the option to distribute |
32 |
* your version of this file under either the CDDL, the GPL Version 2 or |
33 |
* to extend the choice of license to its licensees as provided above. |
34 |
* However, if you add GPL Version 2 code and therefore, elected the GPL |
35 |
* Version 2 license, then the option applies only if the new code is |
36 |
* made subject to such option by the copyright holder. |
37 |
* |
38 |
* Contributor(s): |
39 |
* |
40 |
* Portions Copyrighted 2012 Sun Microsystems, Inc. |
41 |
*/ |
42 |
package org.netbeans.api.quicksearch; |
43 |
|
44 |
import java.awt.Component; |
45 |
import java.awt.KeyboardFocusManager; |
46 |
import java.awt.event.KeyEvent; |
47 |
import java.awt.event.KeyListener; |
48 |
import java.lang.reflect.InvocationTargetException; |
49 |
import java.lang.reflect.Method; |
50 |
import java.util.ArrayList; |
51 |
import java.util.List; |
52 |
import javax.swing.JComponent; |
53 |
import javax.swing.JFrame; |
54 |
import javax.swing.SwingUtilities; |
55 |
import javax.swing.text.Position.Bias; |
56 |
import org.junit.After; |
57 |
import org.junit.AfterClass; |
58 |
import org.junit.Before; |
59 |
import org.junit.Test; |
60 |
import static org.junit.Assert.*; |
61 |
import org.junit.BeforeClass; |
62 |
|
63 |
/** |
64 |
* Test of QuickSearch. |
65 |
* |
66 |
* @author Martin Entlicher |
67 |
*/ |
68 |
public class QuickSearchTest { |
69 |
|
70 |
public QuickSearchTest() { |
71 |
} |
72 |
|
73 |
@BeforeClass |
74 |
public static void setUpClass() throws Exception { |
75 |
} |
76 |
|
77 |
@AfterClass |
78 |
public static void tearDownClass() throws Exception { |
79 |
} |
80 |
|
81 |
@Before |
82 |
public void setUp() { |
83 |
} |
84 |
|
85 |
@After |
86 |
public void tearDown() { |
87 |
} |
88 |
|
89 |
/** |
90 |
* Test of attach and detach methods, of class QuickSearch. |
91 |
*/ |
92 |
@Test |
93 |
public void testAttachDetach() { |
94 |
TestComponent component = new TestComponent(); |
95 |
Object constraints = null; |
96 |
QuickSearch qs = QuickSearch.attach(component, constraints); |
97 |
assertEquals("One added key listener is expected after attach", 1, component.addedKeyListeners.size()); |
98 |
assertTrue(qs.isEnabled()); |
99 |
assertFalse(qs.isAsynchronous()); |
100 |
qs.detach(); |
101 |
assertEquals("No key listener is expected after detach", 0, component.addedKeyListeners.size()); |
102 |
} |
103 |
|
104 |
/** |
105 |
* Test of isEnabled and setEnabled methods, of class QuickSearch. |
106 |
*/ |
107 |
@Test |
108 |
public void testIsEnabled() { |
109 |
TestComponent component = new TestComponent(); |
110 |
Object constraints = null; |
111 |
QuickSearch qs = QuickSearch.attach(component, constraints); |
112 |
assertTrue(qs.isEnabled()); |
113 |
qs.setEnabled(false); |
114 |
assertEquals("No key listener is expected after setEnabled(false)", 0, component.addedKeyListeners.size()); |
115 |
assertFalse(qs.isEnabled()); |
116 |
qs.setEnabled(true); |
117 |
assertTrue(qs.isEnabled()); |
118 |
assertEquals("One added key listener is expected after setEnabled(true)", 1, component.addedKeyListeners.size()); |
119 |
qs.detach(); |
120 |
} |
121 |
|
122 |
/** |
123 |
* Test of the addition of quick search component. |
124 |
*/ |
125 |
@Test |
126 |
public void testQuickSearchAdd() { |
127 |
if (!SwingUtilities.isEventDispatchThread()) { |
128 |
try { |
129 |
SwingUtilities.invokeAndWait(new Runnable() { |
130 |
@Override |
131 |
public void run() { |
132 |
testQuickSearchAdd(); |
133 |
} |
134 |
}); |
135 |
} catch (InterruptedException iex) { |
136 |
fail("interrupted."); |
137 |
} catch (InvocationTargetException itex) { |
138 |
Throwable cause = itex.getCause(); |
139 |
if (cause instanceof AssertionError) { |
140 |
throw (AssertionError) cause; |
141 |
} |
142 |
itex.getCause().printStackTrace(); |
143 |
throw new AssertionError(cause); |
144 |
} |
145 |
return; |
146 |
} |
147 |
TestComponent component = new TestComponent(); |
148 |
Object constraints = null; |
149 |
QuickSearch qs = QuickSearch.attach(component, constraints); |
150 |
component.addNotify(); |
151 |
KeyEvent ke = new KeyEvent(component, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'); |
152 |
//KeyboardFocusManager.getCurrentKeyboardFocusManager().setGlobalFocusOwner(component); |
153 |
try { |
154 |
Method setGlobalFocusOwner = KeyboardFocusManager.class.getDeclaredMethod("setGlobalFocusOwner", Component.class); |
155 |
setGlobalFocusOwner.setAccessible(true); |
156 |
setGlobalFocusOwner.invoke(KeyboardFocusManager.getCurrentKeyboardFocusManager(), component); |
157 |
} catch (Exception ex) { |
158 |
ex.printStackTrace(); |
159 |
throw new AssertionError(ex); |
160 |
} |
161 |
component.dispatchEvent(ke); |
162 |
assertNotNull(component.added); |
163 |
assertNull(component.constraints); |
164 |
qs.detach(); |
165 |
assertNull(component.added); |
166 |
|
167 |
constraints = new Object(); |
168 |
qs = QuickSearch.attach(component, constraints); |
169 |
ke = new KeyEvent(component, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'); |
170 |
component.dispatchEvent(ke); |
171 |
assertNotNull(component.added); |
172 |
assertEquals(constraints, component.constraints); |
173 |
qs.detach(); |
174 |
assertNull(component.added); |
175 |
} |
176 |
|
177 |
/** |
178 |
* Test of the quick search listener. |
179 |
*/ |
180 |
@Test |
181 |
public void testQuickSearchListener() { |
182 |
if (!SwingUtilities.isEventDispatchThread()) { |
183 |
try { |
184 |
SwingUtilities.invokeAndWait(new Runnable() { |
185 |
@Override |
186 |
public void run() { |
187 |
testQuickSearchListener(); |
188 |
} |
189 |
}); |
190 |
} catch (InterruptedException iex) { |
191 |
fail("interrupted."); |
192 |
} catch (InvocationTargetException itex) { |
193 |
Throwable cause = itex.getCause(); |
194 |
if (cause instanceof AssertionError) { |
195 |
throw (AssertionError) cause; |
196 |
} |
197 |
itex.getCause().printStackTrace(); |
198 |
throw new AssertionError(cause); |
199 |
} |
200 |
return; |
201 |
} |
202 |
TestComponent component = new TestComponent(); |
203 |
Object constraints = null; |
204 |
QuickSearch qs = QuickSearch.attach(component, constraints); |
205 |
component.addNotify(); |
206 |
final String[] searchTextPtr = new String[] { null }; |
207 |
final Bias[] biasPtr = new Bias[] { null }; |
208 |
final boolean[] confirmedPtr = new boolean[] { false }; |
209 |
final boolean[] canceledPtr = new boolean[] { false }; |
210 |
QuickSearchListener qsl = new QuickSearchListener() { |
211 |
|
212 |
@Override |
213 |
public void quickSearchUpdate(String searchText) { |
214 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
215 |
searchTextPtr[0] = searchText; |
216 |
} |
217 |
|
218 |
@Override |
219 |
public void showNextSelection(Bias bias) { |
220 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
221 |
biasPtr[0] = bias; |
222 |
} |
223 |
|
224 |
@Override |
225 |
public String findMaxPrefix(String prefix) { |
226 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
227 |
return prefix + "endPrefix"; |
228 |
} |
229 |
|
230 |
@Override |
231 |
public void quickSearchConfirmed() { |
232 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
233 |
confirmedPtr[0] = true; |
234 |
} |
235 |
|
236 |
@Override |
237 |
public void quickSearchCanceled() { |
238 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
239 |
canceledPtr[0] = true; |
240 |
} |
241 |
}; |
242 |
qs.addQuickSearchListener(qsl); |
243 |
// Test that a key event passed to the component triggers the quick search: |
244 |
try { |
245 |
Method setGlobalFocusOwner = KeyboardFocusManager.class.getDeclaredMethod("setGlobalFocusOwner", Component.class); |
246 |
setGlobalFocusOwner.setAccessible(true); |
247 |
setGlobalFocusOwner.invoke(KeyboardFocusManager.getCurrentKeyboardFocusManager(), component); |
248 |
} catch (Exception ex) { |
249 |
ex.printStackTrace(); |
250 |
throw new AssertionError(ex); |
251 |
} |
252 |
KeyEvent ke = new KeyEvent(component, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'); |
253 |
component.dispatchEvent(ke); |
254 |
assertEquals("A", qs.getSearchField().getText()); |
255 |
assertEquals("A", searchTextPtr[0]); |
256 |
assertNull(biasPtr[0]); |
257 |
|
258 |
// Test that further key events passed to the quick search field trigger the quick search listener: |
259 |
qs.getSearchField().setCaretPosition(1); |
260 |
try { |
261 |
Method setGlobalFocusOwner = KeyboardFocusManager.class.getDeclaredMethod("setGlobalFocusOwner", Component.class); |
262 |
setGlobalFocusOwner.setAccessible(true); |
263 |
setGlobalFocusOwner.invoke(KeyboardFocusManager.getCurrentKeyboardFocusManager(), qs.getSearchField()); |
264 |
} catch (Exception ex) { |
265 |
ex.printStackTrace(); |
266 |
throw new AssertionError(ex); |
267 |
} |
268 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'b'); |
269 |
qs.getSearchField().dispatchEvent(ke); |
270 |
assertEquals("Ab", searchTextPtr[0]); |
271 |
|
272 |
// Test the up/down keys resulting to selection navigation: |
273 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_UP, (char) KeyEvent.VK_UP); |
274 |
qs.getSearchField().dispatchEvent(ke); |
275 |
assertEquals(Bias.Backward, biasPtr[0]); |
276 |
|
277 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_DOWN, (char) KeyEvent.VK_DOWN); |
278 |
qs.getSearchField().dispatchEvent(ke); |
279 |
assertEquals(Bias.Forward, biasPtr[0]); |
280 |
|
281 |
// Test that tab adds max prefix: |
282 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB, '\t'); |
283 |
qs.getSearchField().dispatchEvent(ke); |
284 |
assertEquals("AbendPrefix", qs.getSearchField().getText()); |
285 |
|
286 |
// Test that we get no events when quick search listener is detached: |
287 |
qs.removeQuickSearchListener(qsl); |
288 |
qs.getSearchField().setCaretPosition(2); |
289 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'c'); |
290 |
qs.getSearchField().dispatchEvent(ke); |
291 |
assertEquals("AbcendPrefix", qs.getSearchField().getText()); |
292 |
assertEquals("Ab", searchTextPtr[0]); |
293 |
|
294 |
// Test the quick search confirmation on Enter key: |
295 |
qs.addQuickSearchListener(qsl); |
296 |
assertFalse(confirmedPtr[0]); |
297 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_ENTER, '\n'); |
298 |
qs.getSearchField().dispatchEvent(ke); |
299 |
assertTrue(confirmedPtr[0]); |
300 |
|
301 |
// Test the quick search cancel on ESC key: |
302 |
ke = new KeyEvent(component, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'); |
303 |
component.dispatchEvent(ke); |
304 |
assertEquals("A", searchTextPtr[0]); |
305 |
assertFalse(canceledPtr[0]); |
306 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_ESCAPE, (char) 27); |
307 |
qs.getSearchField().dispatchEvent(ke); |
308 |
assertTrue(canceledPtr[0]); |
309 |
} |
310 |
|
311 |
enum sync { W, N } // Wait, Notify |
312 |
|
313 |
/** |
314 |
* Test of asynchronous calls, of class QuickSearch. |
315 |
*/ |
316 |
@Test |
317 |
public void testAsynchronous() { |
318 |
final TestComponent[] componentPtr = new TestComponent[] { null }; |
319 |
final QuickSearch[] qsPtr = new QuickSearch[] { null }; |
320 |
try { |
321 |
SwingUtilities.invokeAndWait(new Runnable() { |
322 |
@Override |
323 |
public void run() { |
324 |
componentPtr[0] = new TestComponent(); |
325 |
qsPtr[0] = QuickSearch.attach(componentPtr[0], null); |
326 |
componentPtr[0].addNotify(); |
327 |
} |
328 |
}); |
329 |
} catch (InterruptedException iex) { |
330 |
fail("interrupted."); |
331 |
} catch (InvocationTargetException itex) { |
332 |
Throwable cause = itex.getCause(); |
333 |
if (cause instanceof AssertionError) { |
334 |
throw (AssertionError) cause; |
335 |
} |
336 |
itex.getCause().printStackTrace(); |
337 |
throw new AssertionError(cause); |
338 |
} |
339 |
final String[] searchTextPtr = new String[] { null }; |
340 |
final Bias[] biasPtr = new Bias[] { null }; |
341 |
final Object findMaxPrefixLock = new Object(); |
342 |
final boolean[] confirmedPtr = new boolean[] { false }; |
343 |
final boolean[] canceledPtr = new boolean[] { false }; |
344 |
final boolean[] asynchronousPtr = new boolean[] { false }; |
345 |
final sync[] syncPtr = new sync[] { null }; |
346 |
QuickSearchListener qsl = new QuickSearchListener() { |
347 |
|
348 |
@Override |
349 |
public void quickSearchUpdate(String searchText) { |
350 |
assertTrue(asynchronousPtr[0] != SwingUtilities.isEventDispatchThread()); |
351 |
synchronized(searchTextPtr) { |
352 |
if (syncPtr[0] == null) { |
353 |
syncPtr[0] = sync.W; |
354 |
// Wait for the notification first |
355 |
try { searchTextPtr.wait(); } catch (InterruptedException iex) {} |
356 |
} |
357 |
searchTextPtr[0] = searchText; |
358 |
searchTextPtr.notifyAll(); |
359 |
syncPtr[0] = null; |
360 |
} |
361 |
} |
362 |
|
363 |
@Override |
364 |
public void showNextSelection(Bias bias) { |
365 |
assertTrue(asynchronousPtr[0] != SwingUtilities.isEventDispatchThread()); |
366 |
synchronized(biasPtr) { |
367 |
if (syncPtr[0] == null) { |
368 |
syncPtr[0] = sync.W; |
369 |
// Wait for the notification first |
370 |
try { biasPtr.wait(); } catch (InterruptedException iex) {} |
371 |
} |
372 |
biasPtr[0] = bias; |
373 |
biasPtr.notifyAll(); |
374 |
syncPtr[0] = null; |
375 |
} |
376 |
} |
377 |
|
378 |
@Override |
379 |
public String findMaxPrefix(String prefix) { |
380 |
assertTrue(asynchronousPtr[0] != SwingUtilities.isEventDispatchThread()); |
381 |
synchronized(findMaxPrefixLock) { |
382 |
if (syncPtr[0] == null) { |
383 |
syncPtr[0] = sync.W; |
384 |
// Wait for the notification first |
385 |
try { findMaxPrefixLock.wait(); } catch (InterruptedException iex) {} |
386 |
} |
387 |
prefix = prefix + "endPrefix"; |
388 |
findMaxPrefixLock.notifyAll(); |
389 |
syncPtr[0] = null; |
390 |
} |
391 |
return prefix; |
392 |
} |
393 |
|
394 |
@Override |
395 |
public void quickSearchConfirmed() { |
396 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
397 |
confirmedPtr[0] = true; |
398 |
} |
399 |
|
400 |
@Override |
401 |
public void quickSearchCanceled() { |
402 |
assertTrue(SwingUtilities.isEventDispatchThread()); |
403 |
canceledPtr[0] = true; |
404 |
} |
405 |
}; |
406 |
qsPtr[0].addQuickSearchListener(qsl); |
407 |
assertFalse(qsPtr[0].isAsynchronous()); |
408 |
qsPtr[0].setAsynchronous(true); |
409 |
asynchronousPtr[0] = true; |
410 |
assertTrue(qsPtr[0].isAsynchronous()); |
411 |
|
412 |
// Test that a key event passed to the component triggers the asynchronous quick search: |
413 |
try { |
414 |
SwingUtilities.invokeAndWait(new Runnable() { |
415 |
@Override |
416 |
public void run() { |
417 |
try { |
418 |
Method setGlobalFocusOwner = KeyboardFocusManager.class.getDeclaredMethod("setGlobalFocusOwner", Component.class); |
419 |
setGlobalFocusOwner.setAccessible(true); |
420 |
setGlobalFocusOwner.invoke(KeyboardFocusManager.getCurrentKeyboardFocusManager(), componentPtr[0]); |
421 |
} catch (Exception ex) { |
422 |
ex.printStackTrace(); |
423 |
throw new AssertionError(ex); |
424 |
} |
425 |
KeyEvent ke = new KeyEvent(componentPtr[0], KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'); |
426 |
componentPtr[0].dispatchEvent(ke); |
427 |
} |
428 |
}); |
429 |
} catch (InterruptedException iex) { |
430 |
fail("interrupted."); |
431 |
} catch (InvocationTargetException itex) { |
432 |
Throwable cause = itex.getCause(); |
433 |
if (cause instanceof AssertionError) { |
434 |
throw (AssertionError) cause; |
435 |
} |
436 |
itex.getCause().printStackTrace(); |
437 |
throw new AssertionError(cause); |
438 |
} |
439 |
synchronized(searchTextPtr) { |
440 |
assertNull(searchTextPtr[0]); |
441 |
syncPtr[0] = sync.N; |
442 |
searchTextPtr.notifyAll(); |
443 |
// Wait to set the value |
444 |
try { searchTextPtr.wait(); } catch (InterruptedException iex) {} |
445 |
assertEquals("A", searchTextPtr[0]); |
446 |
} |
447 |
|
448 |
// Test the up/down keys resulting to asynchronous selection navigation: |
449 |
try { |
450 |
SwingUtilities.invokeAndWait(new Runnable() { |
451 |
@Override |
452 |
public void run() { |
453 |
KeyEvent ke = new KeyEvent(qsPtr[0].getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_UP, (char) KeyEvent.VK_UP); |
454 |
qsPtr[0].getSearchField().dispatchEvent(ke); |
455 |
|
456 |
ke = new KeyEvent(qsPtr[0].getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_DOWN, (char) KeyEvent.VK_DOWN); |
457 |
qsPtr[0].getSearchField().dispatchEvent(ke); |
458 |
} |
459 |
}); |
460 |
} catch (InterruptedException iex) { |
461 |
fail("interrupted."); |
462 |
} catch (InvocationTargetException itex) { |
463 |
Throwable cause = itex.getCause(); |
464 |
if (cause instanceof AssertionError) { |
465 |
throw (AssertionError) cause; |
466 |
} |
467 |
itex.getCause().printStackTrace(); |
468 |
throw new AssertionError(cause); |
469 |
} |
470 |
synchronized(biasPtr) { |
471 |
assertNull(biasPtr[0]); |
472 |
syncPtr[0] = sync.N; |
473 |
biasPtr.notifyAll(); |
474 |
// Wait to set the value |
475 |
try { biasPtr.wait(); } catch (InterruptedException iex) {} |
476 |
assertEquals(Bias.Backward, biasPtr[0]); |
477 |
} |
478 |
synchronized(biasPtr) { |
479 |
assertEquals(Bias.Backward, biasPtr[0]); |
480 |
syncPtr[0] = sync.N; |
481 |
biasPtr.notifyAll(); |
482 |
// Wait to set the value |
483 |
try { biasPtr.wait(); } catch (InterruptedException iex) {} |
484 |
assertEquals(Bias.Forward, biasPtr[0]); |
485 |
} |
486 |
|
487 |
// Test that tab adds max prefix asynchronously: |
488 |
try { |
489 |
SwingUtilities.invokeAndWait(new Runnable() { |
490 |
@Override |
491 |
public void run() { |
492 |
KeyEvent ke = new KeyEvent(qsPtr[0].getSearchField(), KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB, '\t'); |
493 |
qsPtr[0].getSearchField().dispatchEvent(ke); |
494 |
} |
495 |
}); |
496 |
} catch (InterruptedException iex) { |
497 |
fail("interrupted."); |
498 |
} catch (InvocationTargetException itex) { |
499 |
Throwable cause = itex.getCause(); |
500 |
if (cause instanceof AssertionError) { |
501 |
throw (AssertionError) cause; |
502 |
} |
503 |
itex.getCause().printStackTrace(); |
504 |
throw new AssertionError(cause); |
505 |
} |
506 |
synchronized(findMaxPrefixLock) { |
507 |
assertEquals("A", qsPtr[0].getSearchField().getText()); |
508 |
syncPtr[0] = sync.N; |
509 |
findMaxPrefixLock.notifyAll(); |
510 |
// Wait to set the value |
511 |
try { findMaxPrefixLock.wait(); } catch (InterruptedException iex) {} |
512 |
// Can not test it immediatelly, the text is updated in AWT |
513 |
// assertEquals("AendPrefix", qsPtr[0].getSearchField().getText()); |
514 |
} |
515 |
try { Thread.sleep(200); } catch (InterruptedException iex) {} |
516 |
try { |
517 |
SwingUtilities.invokeAndWait(new Runnable() { |
518 |
@Override |
519 |
public void run() { |
520 |
assertEquals("AendPrefix", qsPtr[0].getSearchField().getText()); |
521 |
} |
522 |
}); |
523 |
} catch (InterruptedException iex) { |
524 |
fail("interrupted."); |
525 |
} catch (InvocationTargetException itex) { |
526 |
Throwable cause = itex.getCause(); |
527 |
if (cause instanceof AssertionError) { |
528 |
throw (AssertionError) cause; |
529 |
} |
530 |
itex.getCause().printStackTrace(); |
531 |
throw new AssertionError(cause); |
532 |
} |
533 |
} |
534 |
|
535 |
/** |
536 |
* Test of processKeyEvent method, of class QuickSearch. |
537 |
*/ |
538 |
@Test |
539 |
public void testProcessKeyEvent() { |
540 |
TestComponent component = new TestComponent(); |
541 |
Object constraints = null; |
542 |
QuickSearch qs = QuickSearch.attach(component, constraints); |
543 |
final String[] searchTextPtr = new String[] { null }; |
544 |
final Bias[] biasPtr = new Bias[] { null }; |
545 |
final boolean[] confirmedPtr = new boolean[] { false }; |
546 |
final boolean[] canceledPtr = new boolean[] { false }; |
547 |
QuickSearchListener qsl = new QuickSearchListener() { |
548 |
|
549 |
@Override |
550 |
public void quickSearchUpdate(String searchText) { |
551 |
searchTextPtr[0] = searchText; |
552 |
} |
553 |
|
554 |
@Override |
555 |
public void showNextSelection(Bias bias) { |
556 |
biasPtr[0] = bias; |
557 |
} |
558 |
|
559 |
@Override |
560 |
public String findMaxPrefix(String prefix) { |
561 |
return prefix + "endPrefix"; |
562 |
} |
563 |
|
564 |
@Override |
565 |
public void quickSearchConfirmed() { |
566 |
confirmedPtr[0] = true; |
567 |
} |
568 |
|
569 |
@Override |
570 |
public void quickSearchCanceled() { |
571 |
canceledPtr[0] = true; |
572 |
} |
573 |
}; |
574 |
qs.addQuickSearchListener(qsl); |
575 |
KeyEvent ke = new KeyEvent(component, KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'A'); |
576 |
qs.processKeyEvent(ke); |
577 |
assertEquals("A", qs.getSearchField().getText()); |
578 |
assertEquals("A", searchTextPtr[0]); |
579 |
assertNull(biasPtr[0]); |
580 |
|
581 |
ke = new KeyEvent(qs.getSearchField(), KeyEvent.KEY_TYPED, System.currentTimeMillis(), 0, KeyEvent.VK_UNDEFINED, 'b'); |
582 |
qs.processKeyEvent(ke); |
583 |
assertEquals("Ab", qs.getSearchField().getText()); |
584 |
assertEquals("Ab", searchTextPtr[0]); |
585 |
} |
586 |
|
587 |
/** |
588 |
* Test of findMaxCommonSubstring method, of class QuickSearch. |
589 |
*/ |
590 |
@Test |
591 |
public void testFindMaxCommonSubstring() { |
592 |
System.out.println("findMaxCommonSubstring"); |
593 |
String str1 = "annotation"; |
594 |
String str2 = "antenna"; |
595 |
boolean ignoreCase = false; |
596 |
String expResult = "an"; |
597 |
String result = QuickSearch.findMaxCommonSubstring(str1, str2, ignoreCase); |
598 |
assertEquals(expResult, result); |
599 |
str1 = "Annotation"; |
600 |
expResult = ""; |
601 |
result = QuickSearch.findMaxCommonSubstring(str1, str2, ignoreCase); |
602 |
assertEquals(expResult, result); |
603 |
str1 = "AbCdEf"; |
604 |
str2 = "AbCxxx"; |
605 |
expResult = "AbC"; |
606 |
result = QuickSearch.findMaxCommonSubstring(str1, str2, ignoreCase); |
607 |
assertEquals(expResult, result); |
608 |
} |
609 |
|
610 |
private static final class TestComponent extends JComponent { |
611 |
|
612 |
List<KeyListener> addedKeyListeners = new ArrayList<KeyListener>(); |
613 |
Component added; |
614 |
Object constraints; |
615 |
|
616 |
public TestComponent() { |
617 |
new JFrame().add(this); // To have a parent |
618 |
} |
619 |
|
620 |
@Override |
621 |
public boolean isShowing() { |
622 |
return true; |
623 |
} |
624 |
|
625 |
@Override |
626 |
public Component add(Component comp) { |
627 |
this.added = comp; |
628 |
return super.add(comp); |
629 |
} |
630 |
|
631 |
@Override |
632 |
public void add(Component comp, Object constraints) { |
633 |
this.added = comp; |
634 |
this.constraints = constraints; |
635 |
super.add(comp, constraints); |
636 |
} |
637 |
|
638 |
@Override |
639 |
public void remove(Component comp) { |
640 |
if (comp == this.added) { |
641 |
this.added = null; |
642 |
} |
643 |
super.remove(comp); |
644 |
} |
645 |
|
646 |
@Override |
647 |
public synchronized void addKeyListener(KeyListener l) { |
648 |
addedKeyListeners.add(l); |
649 |
super.addKeyListener(l); |
650 |
} |
651 |
|
652 |
@Override |
653 |
public synchronized void removeKeyListener(KeyListener l) { |
654 |
addedKeyListeners.remove(l); |
655 |
super.removeKeyListener(l); |
656 |
} |
657 |
|
658 |
} |
659 |
} |