Skip to content

Commit 04afd45

Browse files
committed
Add JUnit test for testing of the updates to the CloseAllHandler, also add one small change to the CloseAllHandler execution such that if any e4 parts representing an editor are closed we request re-evaluation of the ActivePart to ensure evaluation logic is re-calculated for the CloseAllHandler.
1 parent 8279c72 commit 04afd45

File tree

5 files changed

+372
-1
lines changed

5 files changed

+372
-1
lines changed

bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/CloseAllHandler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ public Object execute(ExecutionEvent event) throws ExecutionException {
7575
partService.hidePart(part);
7676
}
7777
}
78+
// ensure the EnabledWhenExpression evaluation is performed
79+
// otherwise the 'Close All Editors' will still appear enabled until
80+
// the user clicks/selects a different part
81+
getEvaluationService().requestEvaluation(ISources.ACTIVE_PART_NAME);
7882
}
7983
}
8084
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2009, 2017 IBM Corporation 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+
* IBM Corporation - initial API and implementation
13+
******************************************************************************/
14+
package org.eclipse.e4.ui.tests.application;
15+
16+
import org.eclipse.e4.ui.model.application.ui.basic.MBasicFactory;
17+
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
18+
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
19+
import org.eclipse.e4.ui.workbench.modeling.EPartService;
20+
import org.junit.Test;
21+
22+
public class CloseActiveEditorsTest extends UITest {
23+
24+
private static final String EDITOR_TAG = "Editor"; //$NON-NLS-1$
25+
26+
@Test
27+
public void testActivate_Focus() {
28+
MWindow window = ems.createModelElement(MWindow.class);
29+
application.getChildren().add(window);
30+
31+
MPart partA = ems.createModelElement(MPart.class);
32+
partA.setContributionURI(
33+
"bundleclass://org.eclipse.e4.ui.tests/org.eclipse.e4.ui.tests.application.ClientEditor");
34+
window.getChildren().add(partA);
35+
window.setSelectedElement(partA);
36+
partA.getTags().add(EDITOR_TAG);
37+
partA.getTags().add(EPartService.REMOVE_ON_HIDE_TAG);
38+
39+
MPart editorPart = MBasicFactory.INSTANCE.createPart();
40+
window.getChildren().add(editorPart);
41+
editorPart.setElementId("org.eclipse.e4.ui.compatibility.editor"); //$NON-NLS-1$
42+
editorPart.setContributionURI(
43+
"bundleclass://org.eclipse.ui.workbench/org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor"); //$NON-NLS-1$
44+
editorPart.setCloseable(true);
45+
46+
// Add tags marking as an editor, remove on hide, and the editor id
47+
editorPart.getTags().add("Editor"); //$NON-NLS-1$
48+
editorPart.getTags().add(EPartService.REMOVE_ON_HIDE_TAG);
49+
50+
//
51+
// initialize();
52+
//
53+
// getEngine().createGui(window);
54+
//
55+
// ClientEditor editorB = (ClientEditor) partB.getObject();
56+
//
57+
// assertFalse(editorB.wasFocusCalled());
58+
//
59+
// EPartService partService = window.getContext().get(EPartService.class);
60+
// partService.activate(partB);
61+
//
62+
// assertTrue(editorB.wasFocusCalled());
63+
}
64+
}

tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/api/ApiTestSuite.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.eclipse.ui.tests.api.workbenchpart.OverriddenTitleTest;
2222
import org.eclipse.ui.tests.api.workbenchpart.RawIViewPartTest;
2323
import org.eclipse.ui.tests.api.workbenchpart.ViewPartTitleTest;
24+
import org.eclipse.ui.tests.e4.CloseAllHandlerTest;
2425
import org.eclipse.ui.tests.ide.api.FileEditorInputTest;
2526
import org.eclipse.ui.tests.ide.api.IDETest;
2627
import org.eclipse.ui.tests.ide.api.IDETest2;
@@ -83,7 +84,8 @@
8384
SaveablesListTest.class,
8485
PerspectiveExtensionReaderTest.class,
8586
ModeledPageLayoutTest.class,
86-
WorkbenchPluginTest.class
87+
WorkbenchPluginTest.class,
88+
CloseAllHandlerTest.class
8789
})
8890
public class ApiTestSuite {
8991

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
package org.eclipse.ui.tests.e4;
2+
3+
import java.util.Collections;
4+
import java.util.List;
5+
import java.util.Optional;
6+
7+
import org.eclipse.core.commands.Command;
8+
import org.eclipse.core.commands.ParameterizedCommand;
9+
import org.eclipse.core.resources.IFile;
10+
import org.eclipse.core.resources.IStorage;
11+
import org.eclipse.e4.core.commands.ECommandService;
12+
import org.eclipse.e4.core.commands.EHandlerService;
13+
import org.eclipse.e4.core.contexts.IEclipseContext;
14+
import org.eclipse.e4.ui.model.application.MApplication;
15+
import org.eclipse.e4.ui.model.application.descriptor.basic.MPartDescriptor;
16+
import org.eclipse.e4.ui.model.application.ui.advanced.MArea;
17+
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
18+
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainer;
19+
import org.eclipse.e4.ui.model.application.ui.basic.MPartSashContainerElement;
20+
import org.eclipse.e4.ui.model.application.ui.basic.MPartStack;
21+
import org.eclipse.e4.ui.workbench.IWorkbench;
22+
import org.eclipse.e4.ui.workbench.modeling.EModelService;
23+
import org.eclipse.e4.ui.workbench.modeling.EPartService;
24+
import org.eclipse.e4.ui.workbench.modeling.EPartService.PartState;
25+
import org.eclipse.jface.resource.ImageDescriptor;
26+
import org.eclipse.ui.IEditorPart;
27+
import org.eclipse.ui.IFileEditorInput;
28+
import org.eclipse.ui.IPageLayout;
29+
import org.eclipse.ui.IPersistableElement;
30+
import org.eclipse.ui.ISources;
31+
import org.eclipse.ui.IWorkbenchWindow;
32+
import org.eclipse.ui.PartInitException;
33+
import org.eclipse.ui.internal.CloseAllHandler;
34+
import org.eclipse.ui.internal.Workbench;
35+
import org.junit.Assert;
36+
import org.junit.Before;
37+
import org.junit.Test;
38+
import org.osgi.framework.BundleContext;
39+
import org.osgi.framework.FrameworkUtil;
40+
import org.osgi.framework.ServiceReference;
41+
42+
/**
43+
* @since 3.5
44+
*
45+
*/
46+
public class CloseAllHandlerTest {
47+
48+
private IEclipseContext applicationContext;
49+
private MApplication application;
50+
private EModelService modelService;
51+
private EPartService partService;
52+
53+
private static final String TEST_COMPATIBILITY_LAYER_EDITOR_ID = "org.eclipse.ui.tests.TitleTestEditor"; //$NON-NLS-1$
54+
private static final String CLOSE_ALL_EDITORS_COMMAND_ID = "org.eclipse.ui.file.closeAll"; //$NON-NLS-1$
55+
private static final String DUMMY_E4_PART_ID = "e4_dummy_part_editor"; //$NON-NLS-1$
56+
57+
@Before
58+
public void setUp() throws Exception {
59+
application = getApplicationModel();
60+
applicationContext = application.getContext();
61+
modelService = applicationContext.get(EModelService.class);
62+
partService = application.getContext().get(EPartService.class);
63+
}
64+
65+
private MApplication getApplicationModel() {
66+
BundleContext bundleContext = FrameworkUtil.getBundle(IWorkbench.class).getBundleContext();
67+
ServiceReference<IWorkbench> reference = bundleContext.getServiceReference(IWorkbench.class);
68+
return bundleContext.getService(reference).getApplication();
69+
}
70+
71+
/**
72+
* <p>
73+
* Tests the enabled when and execution logic within the
74+
* {@link CloseAllHandler}.
75+
* </p>
76+
*
77+
* <p>
78+
* Scenario 1: E4 style part contribution which is tagged as representing an
79+
* 'editor' is closed via the handler (and the enablement of handler is
80+
* checked).
81+
* </p>
82+
*
83+
* <p>
84+
* Scenario 2: compatibility layer type editor is closed via the handler (and
85+
* the enablement of handler is checked).
86+
* </p>
87+
*
88+
* <p>
89+
* Scenario 3: a mix of an open compatibility layer type editor *and* an E4
90+
* style part contribution which is tagged as representing an 'editor' are both
91+
* closed via the handler (and the enablement of handler is checked).
92+
* </p>
93+
*/
94+
@Test
95+
public void testCloseMixedEditorTypes() {
96+
EHandlerService handlerService = application.getContext().get(EHandlerService.class);
97+
ECommandService commandService = application.getContext().get(ECommandService.class);
98+
99+
Command closeAllCommand = commandService.getCommand(CLOSE_ALL_EDITORS_COMMAND_ID);
100+
final ParameterizedCommand parameterizedCommand = ParameterizedCommand.generateCommand(closeAllCommand,
101+
Collections.EMPTY_MAP);
102+
103+
// verify the close all editors handler enabledment is false (no editors are
104+
// open yet!)
105+
boolean canExecute = handlerService.canExecute(parameterizedCommand);
106+
Assert.assertFalse(canExecute);
107+
108+
// scenario 1: e4 part descriptor contribution
109+
MPartDescriptor partDescriptor = createDummyPartDescriptor();
110+
application.getDescriptors().add(partDescriptor);
111+
112+
// open our e4 part which represents an editor
113+
MPart dummyPart = createAndOpenE4Part(partDescriptor);
114+
115+
// verify the close all handler is enabled now (since dummy editor has been
116+
// opened)
117+
canExecute = handlerService.canExecute(parameterizedCommand);
118+
Assert.assertTrue(canExecute);
119+
120+
// close all editors (dummy editor should close!)
121+
dummyPart = partService.findPart(DUMMY_E4_PART_ID);
122+
Assert.assertNotNull(dummyPart);
123+
handlerService.executeHandler(parameterizedCommand);
124+
dummyPart = partService.findPart(DUMMY_E4_PART_ID);
125+
Assert.assertNull(dummyPart);
126+
127+
// verify the close all handler is *not* enabled now (since dummy editor has
128+
// been closed)
129+
canExecute = handlerService.canExecute(parameterizedCommand);
130+
Assert.assertFalse(canExecute);
131+
132+
// scenario 2: open a compatibility layer editor
133+
IFileEditorInput input = new DummyFileEditorInput();
134+
Object activeWindow = applicationContext.getActive(ISources.ACTIVE_WORKBENCH_WINDOW_NAME);
135+
Assert.assertTrue("Active workbench window not found.", activeWindow instanceof IWorkbenchWindow);
136+
IWorkbenchWindow window = (IWorkbenchWindow) activeWindow;
137+
try {
138+
window.getActivePage().openEditor(input, TEST_COMPATIBILITY_LAYER_EDITOR_ID);
139+
} catch (PartInitException e) {
140+
Assert.fail("Test Compatibility Editor could not be opened. Further testing cannot complete.");
141+
}
142+
143+
// verify the close all handler is enabled now (since a dummy compatibility
144+
// layer editor has been opened)
145+
canExecute = handlerService.canExecute(parameterizedCommand);
146+
Assert.assertTrue(canExecute);
147+
148+
IEditorPart compatEditor = window.getActivePage().findEditor(input);
149+
Assert.assertNotNull(compatEditor);
150+
handlerService.executeHandler(parameterizedCommand);
151+
compatEditor = window.getActivePage().findEditor(input);
152+
Assert.assertNull(compatEditor);
153+
154+
// verify the close all handler is *not* enabled now (since compatibility layer
155+
// editor has been closed)
156+
canExecute = handlerService.canExecute(parameterizedCommand);
157+
Assert.assertFalse(canExecute);
158+
159+
// scenario 3:
160+
// finally: re-open both the compatibility layer editor *and* the dummy e4 part
161+
// which represents an editor, and verify they are *both* closed when we invoked
162+
// the close all editors handler
163+
dummyPart = createAndOpenE4Part(partDescriptor);
164+
try {
165+
window.getActivePage().openEditor(input, TEST_COMPATIBILITY_LAYER_EDITOR_ID);
166+
} catch (PartInitException e) {
167+
Assert.fail("Test Compatibility Editor could not be opened. Further testing cannot complete.");
168+
}
169+
compatEditor = window.getActivePage().findEditor(input);
170+
Assert.assertNotNull(compatEditor);
171+
dummyPart = partService.findPart(DUMMY_E4_PART_ID);
172+
Assert.assertNotNull(dummyPart);
173+
174+
canExecute = handlerService.canExecute(parameterizedCommand);
175+
Assert.assertTrue(canExecute);
176+
177+
// close all editors
178+
handlerService.executeHandler(parameterizedCommand);
179+
canExecute = handlerService.canExecute(parameterizedCommand);
180+
Assert.assertFalse(canExecute);
181+
182+
// verify they are all closed
183+
compatEditor = window.getActivePage().findEditor(input);
184+
Assert.assertNull(compatEditor);
185+
dummyPart = partService.findPart(DUMMY_E4_PART_ID);
186+
Assert.assertNull(dummyPart);
187+
}
188+
189+
private MPart createAndOpenE4Part(MPartDescriptor partDescriptor) {
190+
Optional<MPartStack> primaryPartStack = findPrimaryConfiguationAreaPartStack(application, modelService);
191+
192+
if (primaryPartStack.isEmpty()) {
193+
Assert.fail("Test cannot proceed as the primary part stack could not be found in the application.");
194+
}
195+
196+
MPart dummyPart = partService.createPart(partDescriptor.getElementId());
197+
primaryPartStack.get().getChildren().add(dummyPart);
198+
partService.showPart(dummyPart.getElementId(), PartState.ACTIVATE);
199+
partService.bringToTop(dummyPart);
200+
201+
return dummyPart;
202+
}
203+
204+
private MPartDescriptor createDummyPartDescriptor() {
205+
MPartDescriptor partDescriptor = modelService.createModelElement(MPartDescriptor.class);
206+
partDescriptor.setAllowMultiple(true);
207+
partDescriptor.setElementId(DUMMY_E4_PART_ID);
208+
partDescriptor.setCloseable(true);
209+
partDescriptor.setLabel(DUMMY_E4_PART_ID);
210+
partDescriptor.getTags().add(Workbench.EDITOR_TAG);
211+
partDescriptor.getTags().add(EPartService.REMOVE_ON_HIDE_TAG);
212+
partDescriptor.setContributionURI("bundleclass://org.eclipse.ui.tests/org.eclipse.ui.tests.e4.DummyEditor");
213+
214+
return partDescriptor;
215+
}
216+
217+
private Optional<MPartStack> findPrimaryConfiguationAreaPartStack(MApplication application,
218+
EModelService modelService) {
219+
List<MArea> areaCandidates = modelService.findElements(application,
220+
IPageLayout.ID_EDITOR_AREA, MArea.class, null,
221+
EModelService.IN_SHARED_ELEMENTS);
222+
if (areaCandidates.size() == 1) {
223+
MArea primaryArea = areaCandidates.get(0);
224+
for (MPartSashContainerElement element : primaryArea.getChildren()) {
225+
if (element instanceof MPartStack) {
226+
return Optional.of((MPartStack) element);
227+
} else if (element instanceof MPartSashContainer) {
228+
return ((MPartSashContainer) element).getChildren().stream().filter(c -> c instanceof MPartStack)
229+
.map(c -> (MPartStack) c).findFirst();
230+
}
231+
}
232+
}
233+
234+
return Optional.empty();
235+
}
236+
237+
private class DummyFileEditorInput implements IFileEditorInput {
238+
@Override
239+
public boolean exists() {
240+
return true;
241+
}
242+
243+
@Override
244+
public ImageDescriptor getImageDescriptor() {
245+
return null;
246+
}
247+
248+
@Override
249+
public String getName() {
250+
return "MyInputFile";
251+
}
252+
253+
@Override
254+
public IPersistableElement getPersistable() {
255+
return null;
256+
}
257+
258+
@Override
259+
public String getToolTipText() {
260+
return "My Input File";
261+
}
262+
263+
@Override
264+
public <T> T getAdapter(Class<T> adapter) {
265+
return null;
266+
}
267+
268+
@Override
269+
public IFile getFile() {
270+
return null;
271+
}
272+
273+
/**
274+
* {@inheritDoc}
275+
*/
276+
@Override
277+
public IStorage getStorage() {
278+
return null;
279+
}
280+
}
281+
282+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2010 IBM Corporation 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+
* IBM Corporation - initial API and implementation
13+
******************************************************************************/
14+
15+
package org.eclipse.ui.tests.e4;
16+
17+
public class DummyEditor {
18+
19+
}

0 commit comments

Comments
 (0)