1 /*******************************************************************************
2  * Copyright (c) 2003, 2015, 2019 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  *     Thibault Le Ouay <thibaultleouay@gmail.com> - Bug 457870
14  *     Stefan Winkler <stefan@winklerweb.net> - bug 178019 - CNF Tooltip support
15  *******************************************************************************/
16 package org.eclipse.ui.tests.navigator;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
20 import static org.junit.Assert.fail;
21 
22 import java.util.HashSet;
23 import java.util.Set;
24 
25 import org.eclipse.core.resources.IProject;
26 import org.eclipse.core.resources.IResource;
27 import org.eclipse.core.resources.IWorkspaceRoot;
28 import org.eclipse.core.resources.ResourcesPlugin;
29 import org.eclipse.core.runtime.CoreException;
30 import org.eclipse.jface.action.ActionContributionItem;
31 import org.eclipse.jface.action.IContributionItem;
32 import org.eclipse.jface.action.MenuManager;
33 import org.eclipse.jface.viewers.IStructuredSelection;
34 import org.eclipse.swt.widgets.TreeItem;
35 import org.eclipse.ui.IWorkbenchPage;
36 import org.eclipse.ui.IWorkbenchWindow;
37 import org.eclipse.ui.PartInitException;
38 import org.eclipse.ui.PlatformUI;
39 import org.eclipse.ui.actions.ActionContext;
40 import org.eclipse.ui.internal.navigator.NavigatorFilterService;
41 import org.eclipse.ui.navigator.CommonNavigator;
42 import org.eclipse.ui.navigator.CommonViewer;
43 import org.eclipse.ui.navigator.INavigatorContentService;
44 import org.eclipse.ui.navigator.NavigatorActionService;
45 import org.eclipse.ui.navigator.resources.ProjectExplorer;
46 import org.eclipse.ui.tests.harness.util.DisplayHelper;
47 import org.eclipse.ui.tests.harness.util.EditorTestHelper;
48 import org.eclipse.ui.tests.harness.util.FileUtil;
49 import org.eclipse.ui.tests.navigator.extension.TestContentProvider;
50 import org.eclipse.ui.tests.navigator.extension.TestContentProviderPipelined;
51 import org.eclipse.ui.tests.navigator.extension.TestContentProviderResource;
52 import org.eclipse.ui.tests.navigator.extension.TestDragAssistant;
53 import org.eclipse.ui.tests.navigator.extension.TestEmptyContentProvider;
54 import org.eclipse.ui.tests.navigator.extension.TestLabelProvider;
55 import org.eclipse.ui.tests.navigator.extension.TestSorterData;
56 import org.eclipse.ui.tests.navigator.extension.TestSorterResource;
57 import org.eclipse.ui.tests.navigator.m12.model.ResourceWrapper;
58 import org.eclipse.ui.tests.navigator.util.TestWorkspace;
59 import org.junit.After;
60 import org.junit.Before;
61 
62 public class NavigatorTestBase {
63 
64 	public static final String COMMON_NAVIGATOR_RESOURCE_EXT = "org.eclipse.ui.navigator.resourceContent";
65 
66 	public static final String COMMON_NAVIGATOR_JAVA_EXT = "org.eclipse.jdt.java.ui.javaContent";
67 
68 	public static final String TEST_VIEWER = "org.eclipse.ui.tests.navigator.TestView";
69 	public static final String TEST_VIEWER_PROGRAMMATIC = "org.eclipse.ui.tests.navigator.ProgrammaticTestView";
70 	public static final String TEST_VIEWER_PIPELINE = "org.eclipse.ui.tests.navigator.PipelineTestView";
71 	public static final String TEST_VIEWER_HIDE_EXTENSIONS = "org.eclipse.ui.tests.navigator.HideAvailableExtensionsTestView";
72 	public static final String TEST_VIEWER_INHERITED = "org.eclipse.ui.tests.navigator.InheritedTestView";
73 	public static final String TEST_VIEWER_NON_COMMONVIEWER = "org.eclipse.ui.tests.navigator.NonCommonViewerTestViewer";
74 	public static final String TEST_VIEWER_FILTER = "org.eclipse.ui.tests.navigator.FilterTestView";
75 	public static final String TEST_VIEWER_INITIAL_ACTIVATION = "org.eclipse.ui.tests.navigator.InitialActivationView";
76 	public static final String TEST_VIEWER_LINK_HELPER = "org.eclipse.ui.tests.navigator.TestLinkHelperView";
77 	public static final String TEST_VIEWER_SHOW_IN = "org.eclipse.ui.tests.navigator.TestShowInView";
78 
79 	public static final String TEST_VIEW_NON_COMMONVIEWER = "org.eclipse.ui.tests.navigator.NonCommonViewerTestView";
80 
81 	public static final String TEST_CONTENT = "org.eclipse.ui.tests.navigator.testContent";
82 	public static final String TEST_CONTENT2 = "org.eclipse.ui.tests.navigator.testContent2";
83 	public static final String TEST_CONTENT_OVERRIDDEN1 = "org.eclipse.ui.tests.navigator.testContentOverridden1";
84 	public static final String TEST_CONTENT_OVERRIDDEN2 = "org.eclipse.ui.tests.navigator.testContentOverridden2";
85 	public static final String TEST_CONTENT_OVERRIDE1 = "org.eclipse.ui.tests.navigator.testContentOverride1";
86 	public static final String TEST_CONTENT_OVERRIDE2 = "org.eclipse.ui.tests.navigator.testContentOverride2";
87 	public static final String TEST_CONTENT_OVERRIDE2_BLANK = "org.eclipse.ui.tests.navigator.testContentOverride2Blank";
88 	public static final String TEST_CONTENT_RESOURCE_OVERRIDE = "org.eclipse.ui.tests.navigator.testContentResourceOverride";
89 	public static final String TEST_CONTENT_PIPELINE = "org.eclipse.ui.tests.navigator.testPipeline";
90 	public static final String TEST_CONTENT_WITH = "org.eclipse.ui.tests.navigator.testContentWith";
91 	public static final String TEST_CONTENT_NO_CHILDREN = "org.eclipse.ui.tests.navigator.testContentNoChildren";
92 	public static final String TEST_CONTENT_EMPTY = "org.eclipse.ui.tests.navigator.testContentEmpty";
93 	public static final String TEST_CONTENT_TOOLTIPS = "org.eclipse.ui.tests.navigator.testContentTooltips";
94 
95 	public static final String TEST_CONTENT_RESOURCE_UNSORTED = "org.eclipse.ui.tests.navigator.resourceContent.unsorted";
96 
97 	public static final String TEST_CONTENT_INITIAL_ACTIVATION_FALSE = "org.eclipse.ui.tests.navigator.testInitialActivationFalse";
98 	public static final String TEST_CONTENT_INITIAL_ACTIVATION_TRUE = "org.eclipse.ui.tests.navigator.testInitialActivationTrue";
99 
100 	public static final String TEST_SIMPLE_CHILDREN1 = "org.eclipse.ui.tests.navigator.testSimpleChildrenContent1";
101 	public static final String TEST_SIMPLE_CHILDREN2 = "org.eclipse.ui.tests.navigator.testSimpleChildrenContent2";
102 	public static final String TEST_SIMPLE_CHILDREN3 = "org.eclipse.ui.tests.navigator.testSimpleChildrenContent3";
103 	public static final String TEST_SIMPLE_CHILDREN_NOT_FOUND = "org.eclipse.ui.tests.navigator.testSimpleChildrenAppearsBeforeNotFound";
104 
105 	public static final String TEST_CONTENT_M12_VIEW = "org.eclipse.ui.tests.navigator.M12View";
106 	public static final String TEST_CONTENT_M12_M1_CONTENT = "org.eclipse.ui.tests.navigator.m12.M1";
107 	public static final String TEST_CONTENT_M12_M1_CONTENT_FIRST_CLASS = "org.eclipse.ui.tests.navigator.m12.M1FirstClass";
108 	public static final String TEST_CONTENT_M12_M2_CONTENT = "org.eclipse.ui.tests.navigator.m12.M2";
109 
110 	public static final String TEST_CONTENT_LABEL1 = "org.eclipse.ui.tests.navigator.testContentLabel1";
111 	public static final String TEST_CONTENT_LABEL2 = "org.eclipse.ui.tests.navigator.testContentLabel2";
112 
113 	public static final String TEST_CONTENT_COMPARATOR_MODEL = "org.eclipse.ui.tests.navigator.testContentComparatorModel";
114 	public static final String TEST_CONTENT_SORTER_MODEL = "org.eclipse.ui.tests.navigator.testContentSorterModel";
115 	public static final String TEST_CONTENT_SORTER_MODEL_OVERRIDE = "org.eclipse.ui.tests.navigator.testContentSorterModel.override";
116 	public static final String TEST_CONTENT_SORTER_MODEL_OVERRIDE_NOSORT = "org.eclipse.ui.tests.navigator.testContentSorterModel.override.nosort";
117 	public static final String TEST_CONTENT_SORTER_RESOURCE = "org.eclipse.ui.tests.navigator.testContentSorterResource";
118 	public static final String TEST_CONTENT_SORTER_RESOURCE_SORTONLY = "org.eclipse.ui.tests.navigator.testContentSorterResource.sortOnly";
119 	public static final String TEST_CONTENT_SORTER_RESOURCE_SORTONLY_OVERRIDE = "org.eclipse.ui.tests.navigator.testContentSorterResource.sortOnly.override";
120 	public static final String TEST_CONTENT_SORTER_RESOURCE_OVERRIDE = "org.eclipse.ui.tests.navigator.testContentSorterResource.override";
121 	public static final String TEST_CONTENT_SORTER_RESOURCE_OVERRIDE_SORTER = "org.eclipse.ui.tests.navigator.testContentSorterResource.override.sorter";
122 
123 	public static final String TEST_CONTENT_REDLABEL = "org.eclipse.ui.tests.navigator.testContentRedLabel";
124 	public static final String TEST_CONTENT_MISSINGLABEL = "org.eclipse.ui.tests.navigator.testContentMissingLabel";
125 	public static final String TEST_CONTENT_DROP_COPY = "org.eclipse.ui.tests.navigator.testContentDropCopy";
126 	public static final String TEST_CONTENT_HAS_CHILDREN = "org.eclipse.ui.tests.navigator.testContentHasChildren";
127 	public static final String TEST_CONTENT_ACTION_PROVIDER = "org.eclipse.ui.tests.navigator.testContentActionProvider";
128 
129 	public static final String TEST_CONTENT_TRACKING_LABEL = "org.eclipse.ui.tests.navigator.testTrackingLabel";
130 
131 	public static final String TEST_CONTENT_JST = "org.eclipse.ui.tests.navigator.jst.ContentProvider";
132 
133 	protected static final String TEST_ACTIVITY = "org.eclipse.ui.tests.navigator.testActivity";
134 	protected static final String TEST_ACTIVITY_PROVIDER = "org.eclipse.ui.tests.navigator.testActivityProvider";
135 
136 	public static final String TEST_ACTION_PROVIDER_PRIORITY = "org.eclipse.ui.tests.navigator.extension.TestActionProviderPriority";
137 
138 	protected static final String ACTION_NESTED = "org.eclipse.ui.tests.navigator.NestedAction";
139 
140 	public static final String TEST_VIEWER_HELP_CONTEXT = "org.eclipse.ui.tests.navigator.testHelpContext";
141 
142 	public static final String TEST_C_CONTENT = "org.eclipse.ui.tests.navigator.cdt.content";
143 
144 	public static final String TEST_FILTER_P1 = "org.eclipse.ui.tests.navigator.filters.p1";
145 	public static final String TEST_FILTER_P2 = "org.eclipse.ui.tests.navigator.filters.p2";
146 
147 	protected String _navigatorInstanceId;
148 
149 	protected Set<IResource> _expectedChildren = new HashSet<>();
150 
151 	protected IProject _project;
152 	protected IProject _p1;
153 	protected IProject _p2;
154 
155 	protected static final int _p1Ind = 0;
156 	protected static final int _p2Ind = 1;
157 	protected static final int _projectInd = 2;
158 
159 	protected static int _projectCount;
160 
161 	protected CommonViewer _viewer;
162 
163 	protected CommonNavigator _commonNavigator;
164 
165 	protected INavigatorContentService _contentService;
166 	protected NavigatorActionService _actionService;
167 
168 	protected boolean _initTestData = true;
169 
170 	protected static final boolean DEBUG = false;
171 
NavigatorTestBase()172 	public NavigatorTestBase() {
173 		// placeholder
174 	}
175 
NavigatorTestBase(String name)176 	public NavigatorTestBase(String name) {
177 		// Nothing
178 	}
179 
180 	@Before
setUp()181 	public void setUp() {
182 
183 		if (_navigatorInstanceId == null) {
184 			throw new RuntimeException("Set the _navigatorInstanceId in the constructor");
185 		}
186 
187 		// Easier if this is not around when not needed
188 		if (!_navigatorInstanceId.equals(ProjectExplorer.VIEW_ID))
189 			try {
190 				EditorTestHelper.showView(ProjectExplorer.VIEW_ID, false);
191 			} catch (PartInitException e) {
192 				fail("Should not throw an exception");
193 			}
194 
195 		TestContentProviderPipelined.resetTest();
196 		TestContentProviderResource.resetTest();
197 		TestSorterData.resetTest();
198 		TestSorterResource.resetTest();
199 		TestLabelProvider.resetTest();
200 		TestDragAssistant.resetTest();
201 		TestEmptyContentProvider.resetTest();
202 
203 		if (_initTestData) {
204 			clearAll();
205 			TestWorkspace.init();
206 
207 			IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
208 			_project = root.getProject("Test"); //$NON-NLS-1$
209 
210 			_expectedChildren.add(_project.getFolder("src")); //$NON-NLS-1$
211 			_expectedChildren.add(_project.getFolder("bin")); //$NON-NLS-1$
212 			_expectedChildren.add(_project.getFile(".project")); //$NON-NLS-1$
213 			_expectedChildren.add(_project.getFile(".classpath")); //$NON-NLS-1$
214 			_expectedChildren.add(_project.getFile("model.properties")); //$NON-NLS-1$
215 
216 			try {
217 				_p1 = ResourcesPlugin.getWorkspace().getRoot().getProject("p1");
218 				_p1.open(null);
219 				_p2 = ResourcesPlugin.getWorkspace().getRoot().getProject("p2");
220 				_p2.open(null);
221 			} catch (CoreException e) {
222 				fail("Should not throw an exception");
223 			}
224 
225 			_projectCount = 3;
226 		}
227 
228 		//lookAt();
229 
230 		showNavigator();
231 		refreshViewer();
232 
233 		_contentService = _viewer.getNavigatorContentService();
234 		_actionService = _commonNavigator.getNavigatorActionService();
235 
236 		((NavigatorFilterService) _contentService.getFilterService()).resetFilterActivationState();
237 
238 	}
239 
lookAt()240 	protected void lookAt() {
241 		DisplayHelper.sleep(1000000);
242 	}
243 
waitForModelObjects()244 	protected void waitForModelObjects() throws Exception {
245 		_project.findMember(TestContentProvider.MODEL_FILE_PATH).touch(null);
246 		// Let build run to load the model objects
247 		DisplayHelper.sleep(50);
248 	}
249 
showNavigator()250 	protected void showNavigator() {
251 		try {
252 			EditorTestHelper.showView(_navigatorInstanceId, true);
253 		} catch (PartInitException e) {
254 			fail("Should not throw an exception");
255 		}
256 
257 		IWorkbenchWindow activeWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
258 		IWorkbenchPage activePage = activeWindow.getActivePage();
259 
260 		_commonNavigator = (CommonNavigator) activePage.findView(_navigatorInstanceId);
261 		_commonNavigator.setFocus();
262 		_viewer = _commonNavigator.getAdapter(CommonViewer.class);
263 	}
264 
265 	@After
tearDown()266 	public void tearDown() {
267 		clearAll();
268 		// Hide it, we want a new one each time
269 		try {
270 			EditorTestHelper.showView(_navigatorInstanceId, false);
271 		} catch (PartInitException e) {
272 			fail("Should not throw an exception");
273 		}
274 	}
275 
clearAll()276 	protected void clearAll() {
277 		IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
278 		for (IProject project : projects) {
279 			try {
280 				FileUtil.delete(project);
281 			} catch (CoreException e) {
282 				fail("Should not throw an exception");
283 			}
284 		}
285 	}
286 
287 	/**
288 	 * Use this to not have to wait for the label provider to refresh after changing
289 	 * the activation.  Otherwise we would have to have a small delay in each test
290 	 * case which we don't want.
291 	 */
refreshViewer()292 	protected void refreshViewer() {
293 		try {
294 			// Setting the text in the tree to be empty forces the
295 			// DecoratingStyledCellLabelProvider
296 			// to refresh immediately and not wait for one that is scheduled to
297 			// run.
298 			TreeItem[] rootItems = _viewer.getTree().getItems();
299 			for (TreeItem rootItem : rootItems) {
300 				rootItem.setText("");
301 			}
302 		} catch (Exception ex) {
303 			// Ignore
304 		}
305 		_viewer.refresh();
306 	}
307 
verifyMenu(IStructuredSelection sel, String item)308 	protected Object verifyMenu(IStructuredSelection sel, String item) {
309 		MenuManager mm = new MenuManager();
310 		_actionService.setContext(new ActionContext(sel));
311 		_actionService.fillContextMenu(mm);
312 
313 		IContributionItem[] items = mm.getItems();
314 		for (IContributionItem item1 : items) {
315 			if (item1 instanceof MenuManager) {
316 				MenuManager childMm = (MenuManager) item1;
317 				if (DEBUG) {
318 					System.out.println("menu text: " + childMm.getMenuText());
319 				}
320 				if (childMm.getMenuText().contains(item))
321 					return childMm;
322 			} else if (item1 instanceof ActionContributionItem) {
323 				ActionContributionItem aci = (ActionContributionItem) item1;
324 				if (DEBUG) {
325 					System.out.println("action text: " + aci.getAction().getText());
326 				}
327 				if (aci.getAction().getText().contains(item))
328 					return aci;
329 			}
330 		}
331 
332 		return null;
333 	}
334 
verifyMenu(IStructuredSelection sel, String item, boolean useNewMenu)335 	protected boolean verifyMenu(IStructuredSelection sel, String item, boolean useNewMenu) {
336 		MenuManager mm = new MenuManager();
337 		_actionService.setContext(new ActionContext(sel));
338 		_actionService.fillContextMenu(mm);
339 
340 		IContributionItem[] items = mm.getItems();
341 
342 		if (useNewMenu) {
343 			MenuManager newMm = (MenuManager) items[1];
344 			items = newMm.getItems();
345 		}
346 
347 		for (IContributionItem i : items) {
348 			if (i instanceof ActionContributionItem) {
349 				ActionContributionItem aci = (ActionContributionItem) i;
350 				if (aci.getAction().getText().startsWith(item))
351 					return true;
352 				if (DEBUG)
353 					System.out.println("action text: " + aci.getAction().getText());
354 			}
355 		}
356 
357 		return false;
358 	}
359 
360 	protected static final boolean ALL = true;
361 	protected static final boolean TEXT = true;
362 
checkItems(TreeItem[] rootItems, TestLabelProvider tlp)363 	protected void checkItems(TreeItem[] rootItems, TestLabelProvider tlp) {
364 		checkItems(rootItems, tlp, ALL, TEXT);
365 	}
366 
checkItemsText(TreeItem[] rootItems, TestLabelProvider tlp, boolean all)367 	protected void checkItemsText(TreeItem[] rootItems, TestLabelProvider tlp, boolean all) {
368 		checkItems(rootItems, tlp, all, TEXT);
369 	}
370 
checkItems(TreeItem[] rootItems, TestLabelProvider tlp, boolean all, boolean text)371 	protected void checkItems(TreeItem[] rootItems, TestLabelProvider tlp, boolean all, boolean text) {
372 		for (TreeItem rootItem : rootItems) {
373 			// Skip the dummy items (for the + placeholder)
374 			if (rootItem.getText() == null || rootItem.getText().equals("")) {
375 				continue;
376 			}
377 			if (text && !rootItem.getText().startsWith(tlp.getColorName())) {
378 				fail("Wrong text: " + rootItem.getText());
379 			}
380 			assertEquals(tlp.backgroundColor, rootItem.getBackground(0));
381 			assertEquals(TestLabelProvider.toForegroundColor(tlp.backgroundColor), rootItem.getForeground(0));
382 			assertEquals(tlp.font, rootItem.getFont(0));
383 			assertEquals(tlp.image, rootItem.getImage(0));
384 			if (all) {
385 				checkItems(rootItem.getItems(), tlp, all, text);
386 			}
387 		}
388 	}
389 
390 	/**
391 	 * Returns the TreeItem whose data is a ResourceWrapper with the specified
392 	 * name.
393 	 */
_findChild(String name, TreeItem[] items)394 	protected TreeItem _findChild(String name, TreeItem[] items) {
395 		for (TreeItem item : items) {
396 			assertTrue("Child " + item + " should be an M1 or M2 resource", item.getData() instanceof ResourceWrapper);
397 			ResourceWrapper rw = (ResourceWrapper) item.getData();
398 			if (name.equals(rw.getResource().getName())) {
399 				return item;
400 			}
401 		}
402 		return null;
403 	}
404 
_expand(TreeItem[] items)405 	protected void _expand(TreeItem[] items) {
406 		for (TreeItem item : items) {
407 			_viewer.setExpandedState(item.getData(), true);
408 		}
409 	}
410 
411 
412 }
413