1 /*
   2  * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.input;
  27 
  28 import static javafx.scene.input.KeyCombination.ALT_DOWN;
  29 import static javafx.scene.input.KeyCombination.CONTROL_ANY;
  30 import static javafx.scene.input.KeyCombination.CONTROL_DOWN;
  31 import static javafx.scene.input.KeyCombination.SHIFT_ANY;
  32 import static javafx.scene.input.KeyCombination.SHIFT_DOWN;
  33 import static org.junit.Assert.assertEquals;
  34 import static org.junit.Assert.assertFalse;
  35 import static org.junit.Assert.assertTrue;
  36 
  37 import java.util.HashMap;
  38 import java.util.Map;
  39 
  40 import javafx.event.Event;
  41 import javafx.scene.input.KeyCombination.ModifierValue;
  42 
  43 import org.junit.AfterClass;
  44 import org.junit.BeforeClass;
  45 import org.junit.Test;
  46 
  47 import com.sun.javafx.pgstub.StubToolkit;
  48 import com.sun.javafx.scene.input.KeyCodeMap;
  49 import com.sun.javafx.tk.Toolkit;
  50 
  51 
  52 public class KeyCombinationTest {
  53     final KeyEvent ctrlAltQEvent = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  54             "q", null, KeyCodeMap.valueOf(0x51), false, true, true, false);
  55 
  56     final KeyEvent ctrlAltQUpEvent = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_RELEASED, 
  57             "q", null, KeyCodeMap.valueOf(0x51), false, true, true, false);
  58 
  59     final KeyEvent ctrlShiftQEvent = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  60             "Q", null, KeyCodeMap.valueOf(0x51), true, true, false, false);
  61 
  62     final KeyEvent ctrlAltShiftQEvent = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  63             "Q", null, KeyCodeMap.valueOf(0x51), true, true, true, false);
  64 
  65     final KeyEvent alt2Event = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  66             "2", null, KeyCodeMap.valueOf(0x32), false, false, true, false);
  67 
  68     final KeyEvent altShift2Event = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  69             "@", null, KeyCodeMap.valueOf(0x32), true, false, true, false);
  70 
  71     final KeyEvent altSoftkey0Event = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  72             "~", null, KeyCodeMap.valueOf(0x1000), false, false, true, false);
  73 
  74     final KeyEvent altShiftSoftkey0Event = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  75             "~", null, KeyCodeMap.valueOf(0x1000), true, false, true, false);
  76 
  77     final KeyEvent altShiftPlusEvent = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  78             "~", null, KeyCodeMap.valueOf(0x209), true, false, true, false);
  79 
  80     final KeyEvent altShiftQuoteEvent = new KeyEvent(null, Event.NULL_SOURCE_TARGET, KeyEvent.KEY_PRESSED, 
  81             "~", null, KeyCodeMap.valueOf(0xDE), true, false, true, false);
  82 
  83     @BeforeClass
  84     public static void setUpCharToKeyCodeMap() {
  85         final Map<String, KeyCode> charToKeyCodeMap =
  86                 new HashMap<String, KeyCode>();
  87 
  88         // LATIN SMALL LETTER Q
  89         charToKeyCodeMap.put("q", KeyCode.Q);
  90 
  91         // LATIN CAPITAL LETTER Q
  92         charToKeyCodeMap.put("Q", KeyCode.Q);
  93 
  94         // LETTER +
  95         charToKeyCodeMap.put("+", KeyCode.PLUS);
  96 
  97         // LETTER '
  98         charToKeyCodeMap.put("'", KeyCode.QUOTE);
  99 
 100         // LATIN SMALL LETTER E WITH CARON
 101         charToKeyCodeMap.put("\u011b", KeyCode.DIGIT2);
 102 
 103         // CYRILLIC SMALL LETTER SHORT I
 104         charToKeyCodeMap.put("\u0439", KeyCode.Q);
 105 
 106         // CYRILLIC CAPITAL LETTER SHORT I
 107         charToKeyCodeMap.put("\u0419", KeyCode.Q);
 108 
 109         // MUSICAL SYMBOL G CLEF
 110         charToKeyCodeMap.put("\ud834\udd1e", KeyCode.SOFTKEY_0);
 111         
 112         ((StubToolkit) Toolkit.getToolkit()).setCharToKeyCodeMap(
 113                 charToKeyCodeMap);
 114     }
 115 
 116     @AfterClass
 117     public static void tearDownCharToKeyCodeMap() {
 118         ((StubToolkit) Toolkit.getToolkit()).setCharToKeyCodeMap(null);
 119     }
 120 
 121     @Test
 122     public void testSimpleKeyCodeCombination() {
 123         KeyCombination ctrlAltQ = new KeyCodeCombination(KeyCode.Q,
 124                                                          CONTROL_DOWN,
 125                                                          ALT_DOWN);
 126 
 127         KeyCombination altCtrlQ = new KeyCodeCombination(KeyCode.Q,
 128                                                          ALT_DOWN,
 129                                                          CONTROL_DOWN);
 130 
 131         KeyCombination ctrlShiftQ = new KeyCodeCombination(KeyCode.Q,
 132                                                            CONTROL_DOWN,
 133                                                            SHIFT_DOWN);
 134 
 135         KeyCombination ctrlAltShiftQ = new KeyCodeCombination(KeyCode.Q,
 136                                                               CONTROL_DOWN,
 137                                                               ALT_DOWN,
 138                                                               SHIFT_DOWN);
 139 
 140         KeyCombination ctrlQ = new KeyCodeCombination(KeyCode.DIGIT0,
 141                                                       CONTROL_DOWN);
 142 
 143         KeyCombination ctrlAltA = new KeyCodeCombination(KeyCode.A,
 144                                                          CONTROL_DOWN,
 145                                                          ALT_DOWN);
 146 
 147         assertTrue(ctrlAltQ.match(ctrlAltQEvent));
 148         assertFalse(ctrlAltQ.match(ctrlShiftQEvent));
 149         assertTrue(altCtrlQ.match(ctrlAltQEvent));
 150         assertFalse(altCtrlQ.match(ctrlShiftQEvent));
 151         assertFalse(ctrlShiftQ.match(ctrlAltQEvent));
 152         assertTrue(ctrlShiftQ.match(ctrlShiftQEvent));
 153         assertFalse(ctrlAltShiftQ.match(ctrlAltQEvent));
 154         assertFalse(ctrlAltShiftQ.match(ctrlShiftQEvent));
 155         assertFalse(ctrlQ.match(ctrlAltQEvent));
 156         assertFalse(ctrlQ.match(ctrlShiftQEvent));
 157         assertFalse(ctrlAltA.match(ctrlAltQEvent));
 158         assertFalse(ctrlAltA.match(ctrlShiftQEvent));
 159         assertTrue(ctrlAltQ.match(ctrlAltQUpEvent));
 160     }
 161 
 162     @Test
 163     public void testKeyCodeCombinationWithIgnore() {
 164         KeyCombination ctrlAltQ = new KeyCodeCombination(KeyCode.Q,
 165                                                          CONTROL_DOWN,
 166                                                          ALT_DOWN);
 167 
 168         KeyCombination ctrlAltIShiftQ = new KeyCodeCombination(KeyCode.Q,
 169                                                                CONTROL_DOWN,
 170                                                                ALT_DOWN,
 171                                                                SHIFT_ANY);
 172 
 173         KeyCombination ctrlAltShiftQ = new KeyCodeCombination(KeyCode.Q,
 174                                                               CONTROL_DOWN,
 175                                                               ALT_DOWN,
 176                                                               SHIFT_DOWN);
 177 
 178         assertTrue(ctrlAltQ.match(ctrlAltQEvent));
 179         assertFalse(ctrlAltQ.match(ctrlAltShiftQEvent));
 180         assertFalse(ctrlAltShiftQ.match(ctrlAltQEvent));
 181         assertTrue(ctrlAltShiftQ.match(ctrlAltShiftQEvent));
 182         assertTrue(ctrlAltIShiftQ.match(ctrlAltQEvent));
 183         assertTrue(ctrlAltIShiftQ.match(ctrlAltShiftQEvent));
 184     }
 185 
 186     @Test
 187     public void testKeyCodeCombinationFromString() {
 188         KeyCombination ctrlAltQ =
 189                 KeyCombination.keyCombination("Ctrl + ALT+Q");
 190 
 191         KeyCombination altCtrlQ = 
 192                 KeyCombination.keyCombination("alt+CtRL  + q");
 193 
 194         KeyCombination ctrlShiftQ = 
 195                 KeyCombination.keyCombination("ctrl+shift+Q");
 196 
 197         KeyCombination ctrlAltShiftQ =
 198                 KeyCombination.keyCombination("ctrl + Alt + shift + Q");
 199 
 200         KeyCombination ctrlQ = KeyCombination.keyCombination("  ctrl+Q  ");
 201 
 202         KeyCombination ctrlAltA = KeyCombination.keyCombination("ctrl+alt+A");
 203 
 204         KeyCombination ctrlIgnoreAltShiftQ =
 205                 KeyCombination.keyCombination("Ctrl + ignore Alt + Shift + Q");
 206         
 207         KeyCombination ctrlIgnoreAltShiftQWithWS1=
 208                 KeyCombination.keyCombination("Ctrl\t \t\n\f\r\u000B+ \t\n\f \r\u000Bignore Alt\n+ Shift\f + Q");
 209 
 210         KeyCombination ctrlIgnoreAltShiftQWithWS2 =
 211                 KeyCombination.keyCombination("Ctrl\r+ignore Alt\u000B+Shift +Q");
 212 
 213         assertTrue(ctrlAltQ.match(ctrlAltQEvent));
 214         assertFalse(ctrlAltQ.match(ctrlShiftQEvent));
 215         assertTrue(altCtrlQ.match(ctrlAltQEvent));
 216         assertFalse(altCtrlQ.match(ctrlShiftQEvent));
 217         assertFalse(ctrlShiftQ.match(ctrlAltQEvent));
 218         assertTrue(ctrlShiftQ.match(ctrlShiftQEvent));
 219         assertFalse(ctrlAltShiftQ.match(ctrlAltQEvent));
 220         assertFalse(ctrlAltShiftQ.match(ctrlShiftQEvent));
 221         assertFalse(ctrlQ.match(ctrlAltQEvent));
 222         assertFalse(ctrlQ.match(ctrlShiftQEvent));
 223         assertFalse(ctrlAltA.match(ctrlAltQEvent));
 224         assertFalse(ctrlAltA.match(ctrlShiftQEvent));
 225         assertTrue(ctrlAltQ.match(ctrlAltQUpEvent));
 226         assertTrue(ctrlIgnoreAltShiftQ.match(ctrlShiftQEvent));
 227         assertTrue(ctrlIgnoreAltShiftQ.match(ctrlAltShiftQEvent));
 228         assertTrue(ctrlIgnoreAltShiftQWithWS1.match(ctrlAltShiftQEvent));
 229         assertTrue(ctrlIgnoreAltShiftQWithWS2.match(ctrlAltShiftQEvent));
 230     }
 231 
 232     @Test
 233     public void testKeyCharacterCombinationFromString() {
 234         KeyCombination ctrlAltQ = 
 235                 KeyCombination.keyCombination("Ctrl + ALT+'Q'");
 236 
 237         KeyCombination altCtrlQ = 
 238                 KeyCombination.keyCombination("alt+CtRL  + 'q'");
 239 
 240         KeyCombination altLatinSmallEWithCaron =
 241                 KeyCombination.keyCombination("alt+\u011b");
 242 
 243         KeyCombination shiftAltLatinSmallEWithCaron =
 244                 KeyCombination.keyCombination("shift+alt+'\u011b'");
 245 
 246         KeyCombination ctrlShiftCyrillicSmallI =
 247                 KeyCombination.keyCombination("ctrl+shift+\u0439");
 248 
 249         KeyCombination ctrlShiftCyrillicCapitalI =
 250                 KeyCombination.keyCombination("  ctrl+ shift+  \u0419");
 251 
 252         KeyCombination ctrlAltShiftCyrillicSmallI =
 253                 KeyCombination.keyCombination("ctrl + Alt + shift + \u0439");
 254 
 255         KeyCombination altIgnoreShiftMusicalSymbolGClef =
 256                 KeyCombination.keyCombination(
 257                     "Alt + ignore shift + \ud834\udd1e ");
 258 
 259         KeyCombination altShiftPlus =
 260                 KeyCombination.keyCombination("Shift + Alt+'+'");
 261 
 262         KeyCombination altShiftQuote1 =
 263                 KeyCombination.keyCombination("Shift + Alt + '\\''");
 264 
 265         KeyCombination altShiftQuote2 =
 266                 KeyCombination.keyCombination("'\\''+Shift+Alt");
 267 
 268         assertTrue(ctrlAltQ.match(ctrlAltQEvent));
 269         assertFalse(ctrlAltQ.match(ctrlShiftQEvent));
 270         assertTrue(altCtrlQ.match(ctrlAltQEvent));
 271         assertFalse(altCtrlQ.match(ctrlShiftQEvent));
 272         assertTrue(altLatinSmallEWithCaron.match(alt2Event));
 273         assertFalse(altLatinSmallEWithCaron.match(altShift2Event));
 274         assertFalse(shiftAltLatinSmallEWithCaron.match(alt2Event));
 275         assertTrue(shiftAltLatinSmallEWithCaron.match(altShift2Event));
 276         assertTrue(ctrlShiftCyrillicSmallI.match(ctrlShiftQEvent));
 277         assertFalse(ctrlShiftCyrillicSmallI.match(ctrlAltShiftQEvent));
 278         assertTrue(ctrlShiftCyrillicCapitalI.match(ctrlShiftQEvent));
 279         assertFalse(ctrlShiftCyrillicCapitalI.match(ctrlAltShiftQEvent));
 280         assertFalse(ctrlAltShiftCyrillicSmallI.match(ctrlShiftQEvent));
 281         assertTrue(ctrlAltShiftCyrillicSmallI.match(ctrlAltShiftQEvent));
 282         assertTrue(altIgnoreShiftMusicalSymbolGClef.match(altSoftkey0Event));
 283         assertTrue(
 284                 altIgnoreShiftMusicalSymbolGClef.match(altShiftSoftkey0Event));
 285         assertTrue(altShiftPlus.match(altShiftPlusEvent));
 286         assertTrue(altShiftQuote1.match(altShiftQuoteEvent));
 287         assertTrue(altShiftQuote2.match(altShiftQuoteEvent));
 288     }
 289 
 290     @Test
 291     public void testGetName() {
 292         KeyCombination ctrlAltVKQ = new KeyCodeCombination(KeyCode.Q,
 293                                                            CONTROL_DOWN,
 294                                                            ALT_DOWN);
 295 
 296         KeyCombination ctrlAltQ = new KeyCharacterCombination("q",
 297                                                               CONTROL_DOWN,
 298                                                               ALT_DOWN);
 299 
 300         KeyCombination ctrlIgnoreShiftA = new KeyCharacterCombination(
 301                                                 "a",
 302                                                 CONTROL_DOWN,
 303                                                 SHIFT_ANY);
 304 
 305         KeyCombination altQuote = new KeyCharacterCombination(
 306                                                 "'",
 307                                                 ALT_DOWN);
 308 
 309         assertEquals("Ctrl+Alt+Q", ctrlAltVKQ.getName());
 310         assertEquals("Ctrl+Alt+'q'", ctrlAltQ.getName());
 311         assertEquals("Ignore Shift+Ctrl+'a'", ctrlIgnoreShiftA.getName());
 312         assertEquals("Alt+'\\''", altQuote.getName());
 313     }
 314 
 315     @Test
 316     public void testKeyCombinationWithShortcutModifier() {
 317         final KeyEvent ctrlC = new KeyEvent(
 318                                    KeyEvent.KEY_PRESSED,
 319                                    "c", null, KeyCodeMap.valueOf(0x43),
 320                                    false, true, false, false);
 321         final KeyEvent metaC = new KeyEvent(
 322                                    KeyEvent.KEY_PRESSED,
 323                                    "c", null, KeyCodeMap.valueOf(0x43),
 324                                    false, false, false, true);
 325         final KeyEvent metaAltC = new KeyEvent(
 326                                    KeyEvent.KEY_PRESSED,
 327                                       "c", null, KeyCodeMap.valueOf(0x43),
 328                                       false, false, true, true);
 329 
 330         final KeyCombination shortcutC =
 331                 KeyCombination.keyCombination("Shortcut+C");
 332         final KeyCombination altIgnoreShortcutC =
 333                 KeyCombination.keyCombination("Alt+Ignore Shortcut+C");
 334 
 335         final StubToolkit toolkit = (StubToolkit) Toolkit.getToolkit();
 336 
 337         toolkit.setPlatformShortcutKey(KeyCode.SHORTCUT);
 338         assertFalse(shortcutC.match(ctrlC));
 339         assertFalse(shortcutC.match(metaC));
 340         assertFalse(shortcutC.match(metaAltC));
 341         assertFalse(altIgnoreShortcutC.match(ctrlC));
 342         assertFalse(altIgnoreShortcutC.match(metaC));
 343         assertFalse(altIgnoreShortcutC.match(metaAltC));
 344 
 345         toolkit.setPlatformShortcutKey(KeyCode.CONTROL);
 346         assertTrue(shortcutC.match(ctrlC));
 347         assertFalse(shortcutC.match(metaC));
 348         assertFalse(shortcutC.match(metaAltC));
 349         assertFalse(altIgnoreShortcutC.match(ctrlC));
 350         assertFalse(altIgnoreShortcutC.match(metaC));
 351         assertFalse(altIgnoreShortcutC.match(metaAltC));
 352 
 353         toolkit.setPlatformShortcutKey(KeyCode.META);
 354         assertFalse(shortcutC.match(ctrlC));
 355         assertTrue(shortcutC.match(metaC));
 356         assertFalse(shortcutC.match(metaAltC));
 357         assertFalse(altIgnoreShortcutC.match(ctrlC));
 358         assertFalse(altIgnoreShortcutC.match(metaC));
 359         assertTrue(altIgnoreShortcutC.match(metaAltC));
 360     }
 361 
 362     @Test(expected=NullPointerException.class)
 363     public void constructor1ShouldThrowNPEForNullKeyCode() {
 364         new KeyCodeCombination(null, ModifierValue.UP,
 365                                      ModifierValue.UP,
 366                                      ModifierValue.UP,
 367                                      ModifierValue.UP,
 368                                      ModifierValue.UP);
 369     }
 370 
 371     @Test(expected=NullPointerException.class)
 372     public void constructor1ShouldThrowNPEForNullKeyCharacter() {
 373         new KeyCharacterCombination(null, ModifierValue.UP,
 374                                           ModifierValue.UP,
 375                                           ModifierValue.UP,
 376                                           ModifierValue.UP,
 377                                           ModifierValue.UP);
 378     }
 379 
 380     @Test(expected=NullPointerException.class)
 381     public void constructor1ShouldThrowNPEForNullModifier() {
 382         new KeyCodeCombination(KeyCode.Q, ModifierValue.UP,
 383                                           null,
 384                                           ModifierValue.UP,
 385                                           ModifierValue.UP,
 386                                           ModifierValue.UP);
 387     }
 388 
 389     @Test(expected=IllegalArgumentException.class)
 390     public void constructor1ShouldThrowIAEForModifierKeyCode() {
 391         new KeyCodeCombination(KeyCode.SHIFT, ModifierValue.UP,
 392                                               ModifierValue.UP,
 393                                               ModifierValue.UP,
 394                                               ModifierValue.UP,
 395                                               ModifierValue.UP);
 396     }
 397 
 398     @Test(expected=IllegalArgumentException.class)
 399     public void constructor1ShouldThrowIAEForUndefinedKeyCode() {
 400         new KeyCodeCombination(KeyCode.UNDEFINED, ModifierValue.UP,
 401                                                   ModifierValue.UP,
 402                                                   ModifierValue.UP,
 403                                                   ModifierValue.UP,
 404                                                   ModifierValue.UP);
 405     }
 406 
 407     @Test(expected=NullPointerException.class)
 408     public void constructor2ShouldThrowNPEForNullKeyCode() {
 409         new KeyCodeCombination(null);
 410     }
 411 
 412     @Test(expected=NullPointerException.class)
 413     public void constructor2ShouldThrowNPEForNullKeyCharacter() {
 414         new KeyCharacterCombination(null);
 415     }
 416 
 417     @Test(expected=NullPointerException.class)
 418     public void constructor2ShouldThrowNPEForNullModifier() {
 419         new KeyCharacterCombination("q", ALT_DOWN, null, SHIFT_ANY);
 420     }
 421 
 422     @Test(expected=IllegalArgumentException.class)
 423     public void constructor2ShouldThrowIAEForModifierKeyCode() {
 424         new KeyCodeCombination(KeyCode.CONTROL);
 425     }
 426 
 427     @Test(expected=IllegalArgumentException.class)
 428     public void constructor2ShouldThrowIAEForUndefinedKeyCode() {
 429         new KeyCodeCombination(KeyCode.UNDEFINED);
 430     }
 431 
 432     @Test(expected=IllegalArgumentException.class)
 433     public void constructor2ShouldThrowIAEForDuplicateModifiers() {
 434         new KeyCodeCombination(KeyCode.Q, 
 435                                ALT_DOWN,
 436                                CONTROL_DOWN,
 437                                ALT_DOWN);
 438     }
 439 
 440     @Test(expected=IllegalArgumentException.class)
 441     public void constructor2ShouldThrowIAEForConflictingModifiers() {
 442         new KeyCodeCombination(KeyCode.Q,  
 443                                SHIFT_DOWN,
 444                                CONTROL_ANY,
 445                                SHIFT_ANY);
 446     }
 447 
 448     @Test(expected=IllegalArgumentException.class)
 449     public void keyCombinationShouldThrowIAEForDuplicateModifiers() {
 450         KeyCombination.keyCombination("Ctrl + Shift + Ctrl + Q");
 451     }
 452 
 453     @Test(expected=IllegalArgumentException.class)
 454     public void keyCombinationShouldThrowIAEForConflictingModifiers() {
 455         KeyCombination.keyCombination("Ctrl + Ignore Shift + Alt + Shift + Q");
 456     }
 457 
 458     @Test(expected=IllegalArgumentException.class)
 459     public void keyCombinationShouldThrowIAEForMissingMainKey() {
 460         KeyCombination.keyCombination("Ctrl + Shift");
 461     }
 462 
 463     @Test(expected=IllegalArgumentException.class)
 464     public void keyCombinationShouldThrowIAEForUndefinedMainKey() {
 465         KeyCombination.keyCombination("Ctrl + Shift + Undefined");
 466     }
 467 
 468     @Test(expected=IllegalArgumentException.class)
 469     public void keyCombinationShouldThrowIAEForExtraMainKey1() {
 470         KeyCombination.keyCombination("Ctrl + Shift + Q + 'W'");
 471     }
 472 
 473     @Test(expected=IllegalArgumentException.class)
 474     public void keyCombinationShouldThrowIAEForExtraMainKey2() {
 475         KeyCombination.keyCombination("Ctrl + Shift + 'W' + Q");
 476     }
 477 
 478     @Test(expected=IllegalArgumentException.class)
 479     public void keyCombinationShouldThrowIAEForInvalidSyntax1() {
 480         KeyCombination.keyCombination("  +  Ctrl + Q");
 481     }
 482 
 483     @Test(expected=IllegalArgumentException.class)
 484     public void keyCombinationShouldThrowIAEForInvalidSyntax2() {
 485         KeyCombination.keyCombination("Ctrl ++ Q");
 486     }
 487 
 488     @Test(expected=IllegalArgumentException.class)
 489     public void keyCombinationShouldThrowIAEForInvalidSyntax3() {
 490         KeyCombination.keyCombination("Ctrl + Q +");
 491     }
 492 
 493     @Test(expected=IllegalArgumentException.class)
 494     public void keyCombinationShouldThrowIAEForUnclosedQuote() {
 495         KeyCombination.keyCombination("Quote '");
 496     }
 497 
 498     @Test
 499     public void keyCombinationShouldUseUnparseableStringAsCharacter() {
 500         KeyCombination multiChar = KeyCombination.keyCombination("Alt'Q'\\'");
 501         assertEquals("Alt'Q'\\'",
 502                 ((KeyCharacterCombination) multiChar).getCharacter());
 503     }
 504 
 505 
 506 
 507 
 508     // ------ Tests for getDisplayText() method
 509 
 510     private void assertPlatformEquals(String expectedWin, String expectedMac, String actual) {
 511         if (com.sun.javafx.PlatformUtil.isMac()) {
 512             assertEquals(expectedMac, actual);
 513         } else {
 514             assertEquals(expectedWin, actual);
 515         }
 516     }
 517 
 518     private void assertPlatformEquals(KeyCombination expectedWin, KeyCombination expectedMac, KeyCombination actual) {
 519         if (com.sun.javafx.PlatformUtil.isMac()) {
 520             assertEquals(expectedMac.getDisplayText(), actual.getDisplayText());
 521         } else {
 522             assertEquals(expectedWin.getDisplayText(), actual.getDisplayText());
 523         }
 524     }
 525 
 526     /*
 527      * check that a KeyCombination constructed with a KeyCodeCombination
 528      * and one constucted with a KeyCharacterCombination will have
 529      * the same text if they are for the same key.
 530      */
 531     @Test public void SameDisplayStringKeyCombinationForCharOrCode() {
 532         KeyCodeCombination acceleratorKeyComboACode = new KeyCodeCombination(KeyCode.A, KeyCombination.CONTROL_DOWN);
 533         KeyCharacterCombination acceleratorKeyComboAChar = new KeyCharacterCombination("A", KeyCombination.CONTROL_DOWN);
 534         assertEquals(acceleratorKeyComboACode.getDisplayText(), acceleratorKeyComboAChar.getDisplayText());
 535     }
 536 
 537     /*
 538      * check that an accelerator constructed with a Shortcut
 539      * displays appropriate platform text.
 540      */
 541     @Test public void checkShortcutModifierChangesDisplayString() {
 542         KeyCombination acceleratorShortcutA = KeyCodeCombination.keyCombination("Shortcut+A");
 543 
 544         // on Windows / Unix shortcut maps to ctrl
 545         KeyCodeCombination acceleratorControlA = new KeyCodeCombination(KeyCode.A, KeyCombination.CONTROL_DOWN);
 546 
 547         // on Mac it maps to meta
 548         KeyCodeCombination acceleratorMetaA = new KeyCodeCombination(KeyCode.A, KeyCombination.META_DOWN);
 549 
 550         assertPlatformEquals(acceleratorControlA, acceleratorMetaA, acceleratorShortcutA);
 551     }
 552 
 553     @Test public void validStringForNonKeyCode() {
 554         KeyCharacterCombination acceleratorKeyCombo = new KeyCharacterCombination("[");
 555         assertEquals("[", acceleratorKeyCombo.getDisplayText());
 556     }
 557 
 558     /*
 559      * check that the KeyCodeCombination for KeyCode.DELETE produces something printable.
 560      * We only display the unicode DELETE char on mac, otherwise we use "Delete".
 561      */
 562     @Test public void validStringForDELETE() {
 563         KeyCodeCombination keyComboDELETE = new KeyCodeCombination(KeyCode.DELETE);
 564         assertPlatformEquals("Delete", "\u2326", keyComboDELETE.getDisplayText());
 565     }
 566 }