Skip to content

Commit 27c8c9d

Browse files
basilevsvogella
andcommitted
Tests for CloseUnrelatedProjectsAction #2636
Co-authored-by: Lars Vogel <Lars.Vogel@vogella.com>
1 parent 0c807b3 commit 27c8c9d

2 files changed

Lines changed: 227 additions & 2 deletions

File tree

tests/org.eclipse.ui.tests.navigator/src/org/eclipse/ui/tests/navigator/NavigatorTestSuite.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2005, 2018, 2023 IBM Corporation and others.
2+
* Copyright (c) 2005 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -21,6 +21,7 @@
2121

2222
import org.eclipse.ui.tests.navigator.cdt.CdtTest;
2323
import org.eclipse.ui.tests.navigator.jst.JstPipelineTest;
24+
import org.eclipse.ui.tests.navigator.resources.CloseUnrelatedProjectsActionTest;
2425
import org.eclipse.ui.tests.navigator.resources.FoldersAsProjectsContributionTest;
2526
import org.eclipse.ui.tests.navigator.resources.NestedResourcesTests;
2627
import org.eclipse.ui.tests.navigator.resources.PathComparatorTest;
@@ -37,7 +38,8 @@
3738
FirstClassM1Tests.class, LinkHelperTest.class, ShowInTest.class, ResourceTransferTest.class,
3839
EvaluationCacheTest.class, ResourceMgmtActionProviderTests.class,
3940
NestedResourcesTests.class, PathComparatorTest.class, FoldersAsProjectsContributionTest.class,
40-
GoBackForwardsTest.class, CopyPasteActionTest.class
41+
GoBackForwardsTest.class, CopyPasteActionTest.class,
42+
CloseUnrelatedProjectsActionTest.class,
4143
// DnDTest.class, // DnDTest.testSetDragOperation() fails
4244
// PerformanceTest.class // Does not pass on all platforms see bug 264449
4345
})
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Lars Vogel 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+
package org.eclipse.ui.tests.navigator.resources;
12+
13+
import static org.junit.jupiter.api.Assertions.assertFalse;
14+
import static org.junit.jupiter.api.Assertions.assertTrue;
15+
16+
import org.eclipse.core.resources.IProject;
17+
import org.eclipse.core.resources.IProjectDescription;
18+
import org.eclipse.core.resources.IWorkspace;
19+
import org.eclipse.core.resources.ResourcesPlugin;
20+
import org.eclipse.core.runtime.CoreException;
21+
import org.eclipse.jface.preference.IPreferenceStore;
22+
import org.eclipse.jface.viewers.StructuredSelection;
23+
import org.eclipse.swt.widgets.Display;
24+
import org.eclipse.swt.widgets.Shell;
25+
import org.eclipse.ui.actions.CloseUnrelatedProjectsAction;
26+
import org.eclipse.ui.internal.ide.IDEInternalPreferences;
27+
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
28+
import org.junit.jupiter.api.AfterEach;
29+
import org.junit.jupiter.api.BeforeEach;
30+
import org.junit.jupiter.api.Test;
31+
32+
public class CloseUnrelatedProjectsActionTest {
33+
34+
private IProject a;
35+
private IProject b;
36+
private IProject c;
37+
private IProject d;
38+
private boolean oldCloseUnrelated;
39+
private Shell shell;
40+
41+
@BeforeEach
42+
public void setUp() throws CoreException {
43+
IPreferenceStore store = IDEWorkbenchPlugin.getDefault().getPreferenceStore();
44+
oldCloseUnrelated = store.getBoolean(IDEInternalPreferences.CLOSE_UNRELATED_PROJECTS);
45+
store.setValue(IDEInternalPreferences.CLOSE_UNRELATED_PROJECTS, true);
46+
IWorkspace ws = ResourcesPlugin.getWorkspace();
47+
long suffix = System.nanoTime();
48+
a = ws.getRoot().getProject("CUPA_A_" + suffix);
49+
b = ws.getRoot().getProject("CUPA_B_" + suffix);
50+
c = ws.getRoot().getProject("CUPA_C_" + suffix);
51+
d = ws.getRoot().getProject("CUPA_D_" + suffix);
52+
a.create(null);
53+
a.open(null);
54+
b.create(null);
55+
b.open(null);
56+
c.create(null);
57+
c.open(null);
58+
59+
IProjectDescription aDesc = a.getDescription();
60+
aDesc.setReferencedProjects(new IProject[] { b });
61+
a.setDescription(aDesc, null);
62+
63+
shell = new Shell(Display.getDefault());
64+
}
65+
66+
@AfterEach
67+
public void tearDown() throws CoreException {
68+
if (shell != null && !shell.isDisposed()) {
69+
shell.dispose();
70+
}
71+
IDEWorkbenchPlugin.getDefault().getPreferenceStore().setValue(IDEInternalPreferences.CLOSE_UNRELATED_PROJECTS,
72+
oldCloseUnrelated);
73+
for (IProject p : new IProject[] { a, b, c, d }) {
74+
if (p != null && p.exists()) {
75+
p.delete(true, true, null);
76+
}
77+
}
78+
}
79+
80+
@Test
81+
public void testDisabledAfterAllUnrelatedProjectsClosedAndSelectionChanges() throws CoreException {
82+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
83+
84+
action.selectionChanged(new StructuredSelection(a));
85+
assertTrue(action.isEnabled(), "action must be enabled while unrelated open project C exists");
86+
87+
c.close(null);
88+
89+
action.selectionChanged(new StructuredSelection(b));
90+
assertFalse(action.isEnabled(), "action must be disabled when no unrelated open project remains");
91+
}
92+
93+
@Test
94+
public void testDisabledAfterAllUnrelatedProjectsAreDeleted() throws CoreException {
95+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
96+
97+
action.selectionChanged(new StructuredSelection(a));
98+
assertTrue(action.isEnabled(), "action must be enabled while unrelated open project C exists");
99+
100+
c.delete(true, true, null);
101+
102+
action.selectionChanged(new StructuredSelection(a));
103+
assertFalse(action.isEnabled(), "action must be disabled when no unrelated open project remains");
104+
}
105+
106+
@Test
107+
public void testDoNotCloseDeleted() throws CoreException {
108+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
109+
110+
action.selectionChanged(new StructuredSelection(a));
111+
assertTrue(action.isEnabled(), "action must be enabled while unrelated open project C exists");
112+
113+
c.delete(true, true, null);
114+
115+
action.selectionChanged(new StructuredSelection(a));
116+
assertFalse(action.isEnabled(), "action must be disabled when no unrelated open project remains");
117+
action.run(); // should not throw
118+
}
119+
120+
@Test
121+
public void testDisabledAfterUnrelatedProjectCreated() throws CoreException {
122+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
123+
c.close(null);
124+
action.selectionChanged(new StructuredSelection(b));
125+
assertFalse(action.isEnabled(), "action must be disabled when no unrelated open project remains");
126+
127+
d.create(null);
128+
d.open(null);
129+
130+
action.selectionChanged(new StructuredSelection(b));
131+
assertTrue(action.isEnabled(), "action must be enabled unrelated project is created");
132+
}
133+
134+
@Test
135+
public void testEnabledAfterDeleteAndReopen() throws CoreException {
136+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
137+
action.selectionChanged(new StructuredSelection(b));
138+
assertTrue(action.isEnabled(), "action must be enabled when and unrelated open project remains");
139+
action.run(); // should not throw
140+
141+
d.create(null);
142+
d.open(null);
143+
144+
action.selectionChanged(new StructuredSelection(b));
145+
assertTrue(action.isEnabled(), "action must be enabled when unrelated project is created");
146+
147+
d.delete(true, true, null);
148+
c.open(null);
149+
150+
action.selectionChanged(new StructuredSelection(b));
151+
assertTrue(action.isEnabled(), "action must be enabled when unrelated project is reopened");
152+
action.run(); // should not throw
153+
}
154+
155+
@Test
156+
public void testDisabledAfterRunAndUnrelatedProjectCreated() throws CoreException {
157+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
158+
action.selectionChanged(new StructuredSelection(b));
159+
assertTrue(action.isEnabled(), "action must be enabled while unrelated open projects exist");
160+
action.run();
161+
162+
d.create(null);
163+
d.open(null);
164+
165+
action.selectionChanged(new StructuredSelection(b));
166+
assertTrue(action.isEnabled(), "action must be enabled unrelated project is created");
167+
}
168+
169+
@Test
170+
public void testDisabledAfterAllUnrelatedProjectsClosed() throws CoreException {
171+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
172+
173+
action.selectionChanged(new StructuredSelection(a));
174+
assertTrue(action.isEnabled(),
175+
"action must be enabled while unrelated open project C exists");
176+
177+
c.close(null);
178+
179+
action.selectionChanged(new StructuredSelection(b));
180+
assertFalse(action.isEnabled(),
181+
"action must be disabled when no unrelated open project remains");
182+
}
183+
184+
@Test
185+
public void testEnabledWhenUnrelatedOpenProjectExists() {
186+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
187+
188+
action.selectionChanged(new StructuredSelection(a));
189+
assertTrue(action.isEnabled(), "expected enabled when unrelated open project C exists");
190+
191+
action.selectionChanged(new StructuredSelection(b));
192+
assertTrue(action.isEnabled(),
193+
"expected enabled when unrelated open project C exists (selection B)");
194+
}
195+
196+
@Test
197+
public void testDisabledWhenSelectionCoversAllOpenProjects() throws CoreException {
198+
c.close(null);
199+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
200+
action.selectionChanged(new StructuredSelection(new Object[] { a, b }));
201+
assertFalse(action.isEnabled(),
202+
"action must be disabled when selection plus its references covers all open projects");
203+
}
204+
205+
@Test
206+
public void testListenerInvalidatesGraphOnProjectClose() throws CoreException {
207+
CloseUnrelatedProjectsAction action = new CloseUnrelatedProjectsAction(() -> shell);
208+
209+
action.selectionChanged(new StructuredSelection(a));
210+
assertTrue(action.isEnabled(),
211+
"action must be enabled while unrelated open project C exists");
212+
213+
// Closing C fires a POST_CHANGE event; the registered listener
214+
// invalidates the cached graph and re-evaluates enablement.
215+
c.close(null);
216+
217+
// Re-select A without manually calling selectionChanged first —
218+
// the graph must already be invalidated by the listener.
219+
action.selectionChanged(new StructuredSelection(a));
220+
assertFalse(action.isEnabled(),
221+
"action must be disabled after listener-driven graph invalidation");
222+
}
223+
}

0 commit comments

Comments
 (0)