/******************************************************************************* * Copyright (c) 2013, 2014 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Simon Scholz <simon.scholz@vogella.com> - Bug 436344 *******************************************************************************/ package org.eclipse.e4.ui.bindings.tests; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.eclipse.core.commands.Category; import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.commands.contexts.Context; import org.eclipse.core.commands.contexts.ContextManager; import org.eclipse.e4.core.commands.CommandServiceAddon; import org.eclipse.e4.core.commands.ECommandService; import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.ui.bindings.BindingServiceAddon; import org.eclipse.e4.ui.bindings.EBindingService; import org.eclipse.e4.ui.bindings.internal.BindingTable; import org.eclipse.e4.ui.bindings.internal.BindingTableManager; import org.eclipse.e4.ui.services.ContextServiceAddon; import org.eclipse.e4.ui.services.EContextService; import org.eclipse.jface.bindings.Binding; import org.eclipse.jface.bindings.TriggerSequence; import org.junit.After; import org.junit.Before; import org.junit.Test; public class BindingLookupTest { private static final String ID_DIALOG = "org.eclipse.ui.contexts.dialog"; private static final String ID_DIALOG_AND_WINDOW = "org.eclipse.ui.contexts.dialogAndWindow"; private static final String ID_WINDOW = "org.eclipse.ui.contexts.window"; private static final String ID_TEXT = "org.eclipse.ui.textScope"; private static final String ID_JAVA = "org.eclipse.jdt.ui.javaScope"; private static final String ID_JS = "org.eclipse.wst.jsdt.ui.javaScriptScope"; final static String[] CONTEXTS = { ID_DIALOG_AND_WINDOW, "DAW", null, ID_DIALOG, "Dialog", ID_DIALOG_AND_WINDOW, ID_WINDOW, "Window", ID_DIALOG_AND_WINDOW, ID_TEXT, "Text Scope", ID_WINDOW, ID_JAVA, "Java scope", ID_TEXT, ID_JS, "JavaScript scope", ID_TEXT, }; private static final String TEST_CAT1 = "test.cat1"; private static final String TEST_ID1 = "test.id1"; private static final String TEST_ID2 = "test.id2"; private IEclipseContext workbenchContext; private void defineCommands(IEclipseContext context) { ECommandService cs = workbenchContext .get(ECommandService.class); Category category = cs.defineCategory(TEST_CAT1, "CAT1", null); cs.defineCommand(TEST_ID1, "ID1", null, category, null); cs.defineCommand(TEST_ID2, "ID2", null, category, null); } @Before public void setUp() { IEclipseContext globalContext = Activator.getDefault() .getGlobalContext(); workbenchContext = globalContext.createChild("workbenchContext"); ContextInjectionFactory.make(CommandServiceAddon.class, workbenchContext); ContextInjectionFactory.make(ContextServiceAddon.class, workbenchContext); ContextInjectionFactory.make(BindingServiceAddon.class, workbenchContext); defineCommands(workbenchContext); defineContexts(workbenchContext); defineBindingTables(workbenchContext); } private void defineContexts(IEclipseContext context) { ContextManager contextManager = context.get(ContextManager.class); for (int i = 0; i < CONTEXTS.length; i += 3) { Context c = contextManager.getContext(CONTEXTS[i]); c.define(CONTEXTS[i + 1], null, CONTEXTS[i + 2]); } EContextService cs = context .get(EContextService.class); cs.activateContext(ID_DIALOG_AND_WINDOW); } private void defineBindingTables(IEclipseContext context) { BindingTableManager btm = context.get(BindingTableManager.class); ContextManager cm = context.get(ContextManager.class); btm.addTable(new BindingTable(cm.getContext(ID_DIALOG_AND_WINDOW))); btm.addTable(new BindingTable(cm.getContext(ID_WINDOW))); btm.addTable(new BindingTable(cm.getContext(ID_DIALOG))); } @After public void tearDown() { workbenchContext.dispose(); workbenchContext = null; } @Test public void testFindBinding() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq = bs.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); Binding perfectMatch = bs.getPerfectMatch(seq); assertEquals(cmd, perfectMatch.getParameterizedCommand()); bs.deactivateBinding(db); assertNull(bs.getPerfectMatch(seq)); bs.activateBinding(db); assertEquals(cmd, bs.getPerfectMatch(seq).getParameterizedCommand()); } @Test public void testMultipleBindings() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq = bs.createSequence("CTRL+5 T"); TriggerSequence seq2 = bs.createSequence("CTRL+2 X"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); db = createDefaultBinding(bs, seq2, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); assertEquals(cmd, bs.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd, bs.getPerfectMatch(seq2).getParameterizedCommand()); } @Test public void testLookupChildBinding() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EBindingService bs1 = c1.get(EBindingService.class ); TriggerSequence seq = bs1.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(bs1, seq, cmd, ID_DIALOG_AND_WINDOW); bs1.activateBinding(db); EBindingService wBS = workbenchContext .get(EBindingService.class); assertEquals(cmd, wBS.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd, bs1.getPerfectMatch(seq).getParameterizedCommand()); bs1.deactivateBinding(db); assertNull(wBS.getPerfectMatch(seq)); assertNull(bs1.getPerfectMatch(seq)); } @Test public void testLookupWithTwoChildren() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd1 = cs.createCommand(TEST_ID1, null); ParameterizedCommand cmd2 = cs.createCommand(TEST_ID2, null); EBindingService wBS = workbenchContext .get(EBindingService.class); TriggerSequence seq = wBS.createSequence("CTRL+5 T"); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EContextService es = c1.get(EContextService.class ); es.activateContext(ID_WINDOW); EBindingService bs1 = c1.get(EBindingService.class ); Binding db = createDefaultBinding(bs1, seq, cmd1, ID_WINDOW); bs1.activateBinding(db); IEclipseContext c2 = workbenchContext.createChild("c2"); EContextService es2 = c2.get(EContextService.class ); es2.activateContext(ID_DIALOG); EBindingService bs2 = c2.get(EBindingService.class ); db = createDefaultBinding(bs1, seq, cmd2, ID_DIALOG); bs2.activateBinding(db); assertEquals(cmd1, wBS.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd1, bs1.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, bs2.getPerfectMatch(seq).getParameterizedCommand()); } @Test public void testLookupWithDifferentActiveChild() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd1 = cs.createCommand(TEST_ID1, null); ParameterizedCommand cmd2 = cs.createCommand(TEST_ID2, null); EBindingService wBS = workbenchContext .get(EBindingService.class); TriggerSequence seq = wBS.createSequence("CTRL+5 T"); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EContextService es = c1.get(EContextService.class ); es.activateContext(ID_WINDOW); EBindingService bs1 = c1.get(EBindingService.class ); Binding db = createDefaultBinding(bs1, seq, cmd1, ID_WINDOW); bs1.activateBinding(db); IEclipseContext c2 = workbenchContext.createChild("c2"); EContextService es2 = c2.get(EContextService.class ); es2.activateContext(ID_DIALOG); EBindingService bs2 = c2.get(EBindingService.class ); db = createDefaultBinding(bs1, seq, cmd2, ID_DIALOG); bs2.activateBinding(db); assertEquals(cmd1, bs1.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, bs2.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd1, wBS.getPerfectMatch(seq).getParameterizedCommand()); c2.activate(); assertEquals(cmd1, bs1.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, bs2.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, wBS.getPerfectMatch(seq).getParameterizedCommand()); c1.activate(); assertEquals(cmd1, bs1.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, bs2.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd1, wBS.getPerfectMatch(seq).getParameterizedCommand()); c2.activate(); assertEquals(cmd1, bs1.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, bs2.getPerfectMatch(seq).getParameterizedCommand()); assertEquals(cmd2, wBS.getPerfectMatch(seq).getParameterizedCommand()); assertTrue(wBS.isPerfectMatch(seq)); } @Test public void testLookupShortcut() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq = bs.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); assertEquals(seq, bs.getBestSequenceFor(cmd)); } @Test public void testLookupShortcuts() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq = bs.createSequence("CTRL+5 T"); TriggerSequence seq2 = bs.createSequence("CTRL+2 X"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); Binding db2 = createDefaultBinding(bs, seq2, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db2); TriggerSequence foundSequence = bs.getBestSequenceFor(cmd); assertNotNull(foundSequence); assertEquals(seq, foundSequence); } @Test public void testLookupBestShortcut() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq2 = bs.createSequence("ALT+5 X"); Binding db2 = createDefaultBinding(bs, seq2, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db2); TriggerSequence seq = bs.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); TriggerSequence foundSequence = bs.getBestSequenceFor(cmd); assertNotNull(foundSequence); assertEquals(seq, foundSequence); } @Test public void testLookupBestShortcutWithChild() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq2 = bs.createSequence("CTRL+5 T"); Binding db2 = createDefaultBinding(bs, seq2, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db2); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EBindingService bs1 = c1.get(EBindingService.class ); TriggerSequence seq = bs1.createSequence("ALT+5 X"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs1.activateBinding(db); TriggerSequence foundSequence = bs.getBestSequenceFor(cmd); assertNotNull(foundSequence); assertEquals(seq2, foundSequence); } @Test public void testLookupShortcutsTwoChildren() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd1 = cs.createCommand(TEST_ID1, null); ParameterizedCommand cmd2 = cs.createCommand(TEST_ID2, null); EBindingService wBS = workbenchContext .get(EBindingService.class); TriggerSequence seq = wBS.createSequence("CTRL+5 T"); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EContextService es = c1.get(EContextService.class ); es.activateContext(ID_WINDOW); EBindingService bs1 = c1.get(EBindingService.class ); Binding db = createDefaultBinding(bs1, seq, cmd1, ID_WINDOW); bs1.activateBinding(db); IEclipseContext c2 = workbenchContext.createChild("c2"); EContextService es2 = c2.get(EContextService.class ); es2.activateContext(ID_DIALOG); EBindingService bs2 = c2.get(EBindingService.class ); Binding db2 = createDefaultBinding(bs2, seq, cmd2, ID_DIALOG); bs2.activateBinding(db2); assertEquals(seq, wBS.getBestSequenceFor(cmd1)); assertNull(wBS.getBestSequenceFor(cmd2)); assertEquals(seq, bs1.getBestSequenceFor(cmd1)); assertNull(bs1.getBestSequenceFor(cmd2)); assertEquals(seq, bs2.getBestSequenceFor(cmd2)); assertNull(bs2.getBestSequenceFor(cmd1)); } @Test public void testLookupAllShortcuts() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService bs = workbenchContext .get(EBindingService.class); TriggerSequence seq2 = bs.createSequence("ALT+5 X"); Binding db2 = createDefaultBinding(bs, seq2, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db2); TriggerSequence seq = bs.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(bs, seq, cmd, ID_DIALOG_AND_WINDOW); bs.activateBinding(db); // the list will always be ordered ArrayList<TriggerSequence> list = new ArrayList<>(); list.add(seq); list.add(seq2); assertEquals(list, bs.getSequencesFor(cmd)); } @Test public void testLookupAllShortcutsWithChild() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService wBS = workbenchContext .get(EBindingService.class); TriggerSequence seq2 = wBS.createSequence("ALT+5 X"); Binding db2 = createDefaultBinding(wBS, seq2, cmd, ID_DIALOG_AND_WINDOW); wBS.activateBinding(db2); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EContextService es = c1.get(EContextService.class ); es.activateContext(ID_WINDOW); EBindingService bs1 = c1.get(EBindingService.class ); TriggerSequence seq = bs1.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(wBS, seq, cmd, ID_WINDOW); bs1.activateBinding(db); // the list will always be ordered ArrayList<TriggerSequence> list = new ArrayList<>(); list.add(seq); list.add(seq2); assertEquals(list, wBS.getSequencesFor(cmd)); } @Test public void testPartialMatch() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); EBindingService wBS = workbenchContext .get(EBindingService.class); TriggerSequence seq2 = wBS.createSequence("ALT+5 X"); Binding db2 = createDefaultBinding(wBS, seq2, cmd, ID_DIALOG_AND_WINDOW); wBS.activateBinding(db2); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EBindingService bs1 = c1.get(EBindingService.class ); TriggerSequence seq = bs1.createSequence("CTRL+5 T"); Binding db = createDefaultBinding(wBS, seq, cmd, ID_DIALOG_AND_WINDOW); bs1.activateBinding(db); TriggerSequence partialMatch = bs1.createSequence("CTRL+5"); TriggerSequence partialNoMatch = bs1.createSequence("CTRL+8"); assertFalse(bs1.isPartialMatch(partialNoMatch)); assertTrue(bs1.isPartialMatch(partialMatch)); } @Test public void testGetPartialMatches() { ECommandService cs = workbenchContext .get(ECommandService.class); ParameterizedCommand cmd = cs.createCommand(TEST_ID1, null); ParameterizedCommand cmd2 = cs.createCommand(TEST_ID2, null); EBindingService wBS = workbenchContext .get(EBindingService.class); TriggerSequence seq2 = wBS.createSequence("ALT+5 X"); Binding wbBind = createDefaultBinding(wBS, seq2, cmd, ID_DIALOG_AND_WINDOW); wBS.activateBinding(wbBind); IEclipseContext c1 = workbenchContext.createChild("c1"); c1.activate(); EBindingService bs1 = c1.get(EBindingService.class); TriggerSequence seq = bs1.createSequence("CTRL+5 T"); Binding b1 = createDefaultBinding(wBS, seq, cmd, ID_DIALOG_AND_WINDOW); bs1.activateBinding(b1); TriggerSequence sseq = bs1.createSequence("CTRL+5 Y"); Binding b2 = createDefaultBinding(bs1, sseq, cmd2, ID_DIALOG_AND_WINDOW); bs1.activateBinding(b2); ArrayList<Binding> commandMatches = new ArrayList<>(); commandMatches.add(b1); commandMatches.add(b2); TriggerSequence partialMatch = bs1.createSequence("CTRL+5"); TriggerSequence partialNoMatch = bs1.createSequence("CTRL+8"); assertFalse(bs1.isPartialMatch(partialNoMatch)); assertTrue(bs1.isPartialMatch(partialMatch)); Collection<Binding> matches = bs1.getPartialMatches(partialMatch); assertEquals(commandMatches, matches); } private Binding createDefaultBinding(EBindingService bs, TriggerSequence sequence, ParameterizedCommand command, String contextId) { Map<String, String> attrs = new HashMap<>(); attrs.put("schemeId", "org.eclipse.ui.defaultAcceleratorConfiguration"); return bs.createBinding(sequence, command, contextId, attrs); } }