1 /******************************************************************************* 2 * Copyright (c) 2008, 2015, 2019 Oakland Software Incorporated 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 * Oakland Software Incorporated - initial API and implementation 13 *.....IBM Corporation - fixed dead code warning 14 * Fair Issac Corp - bug 287103 - NCSLabelProvider does not properly handle overrides 15 * Thibault Le Ouay <thibaultleouay@gmail.com> - Bug 457870 16 * Stefan Winkler <stefan@winklerweb.net> - bug 178019 - CNF Tooltip support 17 *******************************************************************************/ 18 package org.eclipse.ui.tests.navigator; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertTrue; 22 import static org.junit.Assert.fail; 23 24 import org.eclipse.core.resources.IFile; 25 import org.eclipse.jface.viewers.ILabelProvider; 26 import org.eclipse.jface.viewers.IToolTipProvider; 27 import org.eclipse.jface.viewers.ITreeContentProvider; 28 import org.eclipse.swt.widgets.TreeItem; 29 import org.eclipse.ui.internal.navigator.extensions.NavigatorContentExtension; 30 import org.eclipse.ui.tests.harness.util.DisplayHelper; 31 import org.eclipse.ui.tests.navigator.extension.TestEmptyContentProvider; 32 import org.eclipse.ui.tests.navigator.extension.TestLabelProvider; 33 import org.eclipse.ui.tests.navigator.extension.TestLabelProviderBlank; 34 import org.eclipse.ui.tests.navigator.extension.TestLabelProviderCyan; 35 import org.eclipse.ui.tests.navigator.extension.TestLabelProviderStyledGreen; 36 import org.eclipse.ui.tests.navigator.extension.TrackingLabelProvider; 37 import org.junit.Test; 38 39 public class LabelProviderTest extends NavigatorTestBase { 40 41 private static final boolean PRINT_DEBUG_INFO = false; 42 private static final boolean SLEEP_LONG = false; 43 LabelProviderTest()44 public LabelProviderTest() { 45 _navigatorInstanceId = "org.eclipse.ui.tests.navigator.OverrideTestView"; 46 } 47 48 private static final int NONE = 0; 49 private static final int OVERRIDDEN = 1; 50 private static final int OVERRIDING = 2; 51 private static final int BOTH = 3; 52 53 private static final boolean BLANK = true; 54 private static final boolean NULL = false; 55 56 private static final String PLAIN = "Plain"; 57 setBlank(String cpToGet, boolean blank)58 private void setBlank(String cpToGet, boolean blank) { 59 NavigatorContentExtension ext = (NavigatorContentExtension) _contentService 60 .getContentExtensionById(cpToGet); 61 TestLabelProvider tp = (TestLabelProvider) ext.getLabelProvider(); 62 if (blank) 63 tp._blank = true; 64 else 65 tp._null = true; 66 67 } 68 69 // Bug 289090 label provider returning blank in getText() not properly 70 // skipped 71 // Bug 296253 blank label provider should be allowed if nothing better found blankLabelProviderOverride(int nce, boolean blank, String suffix)72 public void blankLabelProviderOverride(int nce, boolean blank, String suffix) throws Exception { 73 74 String overriddenCp = TEST_CONTENT_OVERRIDDEN1 + suffix; // Red 75 String overrideCp = TEST_CONTENT_OVERRIDE1 + suffix; // Green 76 77 String checkColor = "Green"; 78 79 switch (nce) { 80 case NONE: 81 break; 82 case OVERRIDDEN: 83 setBlank(overriddenCp, blank); 84 break; 85 case OVERRIDING: 86 checkColor = "Red"; 87 setBlank(overrideCp, blank); 88 break; 89 case BOTH: 90 setBlank(overriddenCp, blank); 91 setBlank(overrideCp, blank); 92 break; 93 } 94 95 _contentService.bindExtensions(new String[] { overriddenCp, overrideCp }, false); 96 _contentService.getActivationService().activateExtensions( 97 new String[] { overrideCp, overriddenCp }, true); 98 99 refreshViewer(); 100 101 // This tests the getStyledText() method 102 TreeItem[] rootItems = _viewer.getTree().getItems(); 103 104 // Also test the raw ILabelProvider which uses the getText() method 105 ILabelProvider lp = _contentService.createCommonLabelProvider(); 106 String lpText = lp.getText(rootItems[0].getData()); 107 108 if (nce == BOTH) { 109 if (!rootItems[0].getText().isEmpty()) 110 fail("Wrong text: " + rootItems[0].getText()); 111 112 if (blank) { 113 if (!lpText.isEmpty()) 114 fail("Wrong text from ILabelProvider: " + lpText); 115 } else { 116 if (lpText != null) 117 fail("Wrong text from ILabelProvider: " + lpText); 118 } 119 } else { 120 if (!rootItems[0].getText().startsWith(checkColor)) 121 fail("Wrong text: " + rootItems[0].getText()); 122 if (!lpText.startsWith(checkColor)) 123 fail("Wrong text from ILabelProvider: " + lpText); 124 } 125 } 126 127 @Test testBlankLabelProviderOverrideNone()128 public void testBlankLabelProviderOverrideNone() throws Exception { 129 blankLabelProviderOverride(NONE, BLANK, ""); 130 } 131 132 @Test testNullLabelProviderOverrideNone()133 public void testNullLabelProviderOverrideNone() throws Exception { 134 blankLabelProviderOverride(NONE, NULL, ""); 135 } 136 137 @Test testPlainBlankLabelProviderOverrideNone()138 public void testPlainBlankLabelProviderOverrideNone() throws Exception { 139 blankLabelProviderOverride(NONE, BLANK, PLAIN); 140 } 141 142 @Test testPlainNullLabelProviderOverrideNone()143 public void testPlainNullLabelProviderOverrideNone() throws Exception { 144 blankLabelProviderOverride(NONE, NULL, PLAIN); 145 } 146 147 @Test testBlankLabelProviderOverride1()148 public void testBlankLabelProviderOverride1() throws Exception { 149 blankLabelProviderOverride(OVERRIDDEN, BLANK, ""); 150 } 151 152 @Test testNullLabelProviderOverride1()153 public void testNullLabelProviderOverride1() throws Exception { 154 blankLabelProviderOverride(OVERRIDDEN, NULL, ""); 155 } 156 157 @Test testPlainBlankLabelProviderOverride1()158 public void testPlainBlankLabelProviderOverride1() throws Exception { 159 blankLabelProviderOverride(OVERRIDDEN, BLANK, PLAIN); 160 } 161 162 @Test testPlainNullLabelProviderOverride1()163 public void testPlainNullLabelProviderOverride1() throws Exception { 164 blankLabelProviderOverride(OVERRIDDEN, NULL, PLAIN); 165 } 166 167 @Test testBlankLabelProviderOverride2()168 public void testBlankLabelProviderOverride2() throws Exception { 169 blankLabelProviderOverride(OVERRIDING, BLANK, ""); 170 } 171 172 @Test testNullLabelProviderOverride2()173 public void testNullLabelProviderOverride2() throws Exception { 174 blankLabelProviderOverride(OVERRIDING, NULL, ""); 175 } 176 177 @Test testPlainBlankLabelProviderOverride2()178 public void testPlainBlankLabelProviderOverride2() throws Exception { 179 blankLabelProviderOverride(OVERRIDING, BLANK, PLAIN); 180 } 181 182 @Test testPlainNullLabelProviderOverride2()183 public void testPlainNullLabelProviderOverride2() throws Exception { 184 blankLabelProviderOverride(OVERRIDING, NULL, PLAIN); 185 } 186 187 @Test testBlankLabelProviderBoth()188 public void testBlankLabelProviderBoth() throws Exception { 189 blankLabelProviderOverride(BOTH, BLANK, ""); 190 } 191 192 @Test testNullLabelProviderBoth()193 public void testNullLabelProviderBoth() throws Exception { 194 blankLabelProviderOverride(BOTH, NULL, ""); 195 } 196 197 @Test testPlainBlankLabelProviderBoth()198 public void testPlainBlankLabelProviderBoth() throws Exception { 199 blankLabelProviderOverride(BOTH, BLANK, PLAIN); 200 } 201 202 @Test testPlainNullLabelProviderBoth()203 public void testPlainNullLabelProviderBoth() throws Exception { 204 blankLabelProviderOverride(BOTH, NULL, PLAIN); 205 } 206 207 // bug 252293 [CommonNavigator] LabelProviders do not obey override rules 208 @Test testSimpleResFirst()209 public void testSimpleResFirst() throws Exception { 210 211 _contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN1, 212 TEST_CONTENT_OVERRIDE1 }, false); 213 _contentService.getActivationService().activateExtensions( 214 new String[] { TEST_CONTENT_OVERRIDE1, TEST_CONTENT_OVERRIDDEN1 }, true); 215 216 refreshViewer(); 217 218 TreeItem[] rootItems = _viewer.getTree().getItems(); 219 checkItems(rootItems, TestLabelProviderStyledGreen.instance); 220 } 221 222 /** 223 * E{low} overrides D{low} overrides B{normal} overrides A F{high} overrides 224 * C{low} overrides A G{normal} overrides C{low}. 225 * 226 * F is the highest priority and not overridden, so it's first. 227 * B is next, but is overridden by E and D. So we have FEDB. Then A is processed 228 * which is overridden by B and C which is overridden by B, so we have FEDBGCA. 229 */ 230 @Test testOverrideChain()231 public void testOverrideChain() throws Exception { 232 final String[] EXTENSIONS = new String[] { TEST_CONTENT_TRACKING_LABEL + ".A", 233 TEST_CONTENT_TRACKING_LABEL + ".B", TEST_CONTENT_TRACKING_LABEL + ".C", 234 TEST_CONTENT_TRACKING_LABEL + ".D", TEST_CONTENT_TRACKING_LABEL + ".E", 235 TEST_CONTENT_TRACKING_LABEL + ".F", TEST_CONTENT_TRACKING_LABEL + ".G" }; 236 _contentService.bindExtensions(EXTENSIONS, true); 237 _contentService.getActivationService().activateExtensions(EXTENSIONS, true); 238 239 refreshViewer(); 240 _viewer.getTree().getItems(); 241 242 TrackingLabelProvider.resetQueries(); 243 244 // Time for the decorating label provider to settle down 245 DisplayHelper.sleep(200); 246 247 refreshViewer(); 248 249 // The label provider (sync runs) and then the decorating label provider 250 // runs (in something like every 100ms) 251 // Give time for both and expect both to have happened. 252 DisplayHelper.sleep(200); 253 254 //final String EXPECTED = "FEDBGCA"; 255 //final String EXPECTED = "FGEDBCA"; 256 if (PRINT_DEBUG_INFO) 257 System.out.println("Map: " + TrackingLabelProvider.styledTextQueries); 258 String queries = (String) TrackingLabelProvider.styledTextQueries.get(_project); 259 // This can happen multiple times depending on when the decorating label 260 // provider runs, so just make sure the sequence is right 261 assertTrue("F has the highest priority", queries.startsWith("F")); 262 assertBefore(queries, 'C', 'A'); 263 assertBefore(queries, 'B', 'A'); 264 assertBefore(queries, 'D', 'B'); 265 assertBefore(queries, 'E', 'D'); 266 assertBefore(queries, 'F', 'C'); 267 assertBefore(queries, 'G', 'C'); 268 } 269 270 /** 271 * @param queries 272 * @param firstChar 273 * @param secondChar 274 */ assertBefore(String queries, char firstChar, char secondChar)275 private void assertBefore(String queries, char firstChar, char secondChar) { 276 boolean first = false; 277 final int LEN = queries.length(); 278 for (int i=0; i<LEN; i++) { 279 char cur = queries.charAt(i); 280 if (cur == firstChar) { 281 first = true; 282 } 283 if (cur == secondChar) { 284 assertTrue("Failed to find " + firstChar + " before " + secondChar + " in " + queries, first); 285 return; 286 } 287 } 288 } 289 290 // bug 252293 [CommonNavigator] LabelProviders do not obey override rules 291 @Test testSimpleResLast()292 public void testSimpleResLast() throws Exception { 293 _contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN2, 294 TEST_CONTENT_OVERRIDE2 }, false); 295 _contentService.getActivationService().activateExtensions( 296 new String[] { TEST_CONTENT_OVERRIDDEN2, TEST_CONTENT_OVERRIDE2 }, true); 297 298 refreshViewer(); 299 300 if (SLEEP_LONG) 301 DisplayHelper.sleep(10000000); 302 303 TreeItem[] rootItems = _viewer.getTree().getItems(); 304 checkItems(rootItems, TestLabelProviderCyan.instance); 305 } 306 307 @Test testOverrideAdd()308 public void testOverrideAdd() throws Exception { 309 _contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN2, 310 TEST_CONTENT_OVERRIDE2 }, false); 311 _contentService.getActivationService().activateExtensions( 312 new String[] { TEST_CONTENT_OVERRIDDEN2, TEST_CONTENT_OVERRIDE2 }, true); 313 314 refreshViewer(); 315 316 // Try manually adding 317 _viewer.expandToLevel(_project, 3); 318 IFile f = _project.getFile("newfile"); 319 _viewer.add(_project, new Object[] { f }); 320 321 if (SLEEP_LONG) 322 DisplayHelper.sleep(10000000); 323 324 TreeItem[] rootItems = _viewer.getTree().getItems(); 325 checkItems(rootItems, TestLabelProviderCyan.instance); 326 } 327 328 // Bug 299438 activating extensions does not properly refresh 329 @Test testChangeActivation()330 public void testChangeActivation() throws Exception { 331 TreeItem[] rootItems = _viewer.getTree().getItems(); 332 checkItems(rootItems, TestLabelProviderStyledGreen.instance); 333 334 _contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN2, 335 TEST_CONTENT_OVERRIDE2 }, false); 336 _contentService.getActivationService().activateExtensions( 337 new String[] { TEST_CONTENT_OVERRIDDEN2, TEST_CONTENT_OVERRIDE2 }, true); 338 339 _viewer.expandAll(); 340 341 //System.out.println(System.currentTimeMillis() + " after expand"); 342 343 // Let the label provider refresh - wait up to 60 seconds 344 for (int i = 0; i < 1200; i++) { 345 rootItems = _viewer.getTree().getItems(); 346 //System.out.println("checking text: " + rootItems[0].getText()); 347 if (rootItems[0].getBackground(0).equals(TestLabelProviderCyan.instance.backgroundColor)) 348 break; 349 //System.out.println(System.currentTimeMillis() + " before sleep " + i); 350 DisplayHelper.sleep(50); 351 } 352 353 //System.out.println(System.currentTimeMillis() + " after sleep"); 354 355 if (SLEEP_LONG) 356 DisplayHelper.sleep(10000000); 357 358 // Wait a little bit still to give the rest of the tree time to refresh 359 DisplayHelper.sleep(500); 360 361 rootItems = _viewer.getTree().getItems(); 362 checkItems(rootItems, TestLabelProviderCyan.instance); 363 } 364 365 // Make sure that it finds label providers that are in overridden content 366 // extensions 367 // if none of the label providers from the desired content extensions return 368 // anything 369 @Test testUsingOverriddenLabelProvider()370 public void testUsingOverriddenLabelProvider() throws Exception { 371 372 _contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN2, 373 TEST_CONTENT_OVERRIDE2_BLANK }, true); 374 _contentService.getActivationService().activateExtensions( 375 new String[] { TEST_CONTENT_OVERRIDDEN2, TEST_CONTENT_OVERRIDE2_BLANK }, true); 376 377 refreshViewer(); 378 379 TreeItem[] rootItems = _viewer.getTree().getItems(); 380 381 if (SLEEP_LONG) 382 DisplayHelper.sleep(10000000); 383 384 // But we get the text from the overridden label provider 385 if (!rootItems[0].getText().startsWith("Blue")) 386 fail("Wrong text: " + rootItems[0].getText()); 387 388 // We get the everything else from the blank label provider 389 checkItems(rootItems, TestLabelProviderBlank.instance, ALL, !TEXT); 390 } 391 392 // Bug 295803 Source of contribution set to lowest priority NCE 393 @Test testMultiNceSameObject()394 public void testMultiNceSameObject() throws Exception { 395 396 _contentService.bindExtensions(new String[] { TEST_CONTENT_OVERRIDDEN1, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 397 // Just two different ones, they don't override, the label provider 398 // should be associated with the higher priority extension that 399 // contributed the object. 400 _contentService.getActivationService().activateExtensions( 401 new String[] { TEST_CONTENT_OVERRIDDEN1, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 402 403 refreshViewer(); 404 405 TreeItem[] rootItems = _viewer.getTree().getItems(); 406 407 // DisplayHelper.sleep(10000000); 408 409 // But we get the text from the overridden label provider 410 if (!rootItems[0].getText().equals("p1")) 411 fail("Wrong text: " + rootItems[0].getText()); 412 } 413 414 // Bug 307132 label provider priority not respected 415 @Test testLabelProviderPriority()416 public void testLabelProviderPriority() throws Exception { 417 418 _contentService.bindExtensions(new String[] { TEST_CONTENT_EMPTY, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 419 // Just two different ones, they don't override, the label provider 420 // should be associated with the higher priority extension that 421 // contributed the object. 422 _contentService.getActivationService().activateExtensions( 423 new String[] { TEST_CONTENT_EMPTY, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 424 425 refreshViewer(); 426 427 TreeItem[] rootItems = _viewer.getTree().getItems(); 428 429 //DisplayHelper.sleep(10000000); 430 431 // The empty content provider provides the label at a higher priority 432 // than the resource content provider 433 assertEquals(TestLabelProviderCyan.instance.image, rootItems[0].getImage(0)); 434 } 435 436 // Bug 189986 add SafeRunner for everything 437 @Test testLabelProviderThrow()438 public void testLabelProviderThrow() throws Exception { 439 440 _contentService.bindExtensions(new String[] { TEST_CONTENT_EMPTY, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 441 _contentService.getActivationService().activateExtensions( 442 new String[] { TEST_CONTENT_EMPTY, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 443 444 TestLabelProvider._throw = true; 445 TestEmptyContentProvider._throw = true; 446 447 refreshViewer(); 448 // Have to look at the log to see a bunch of stuff thrown 449 } 450 451 @Test testLabelProviderSupportsTooltip()452 public void testLabelProviderSupportsTooltip() throws Exception { 453 _contentService.bindExtensions(new String[] { TEST_CONTENT_TOOLTIPS, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 454 _contentService.getActivationService() 455 .activateExtensions(new String[] { TEST_CONTENT_TOOLTIPS, COMMON_NAVIGATOR_RESOURCE_EXT }, true); 456 457 refreshViewer(); 458 459 assertTrue(_viewer.getLabelProvider() instanceof IToolTipProvider); 460 IToolTipProvider tooltipProvider = (IToolTipProvider) _viewer.getLabelProvider(); 461 462 assertTrue(_viewer.getContentProvider() instanceof ITreeContentProvider); 463 ITreeContentProvider contentProvider = (ITreeContentProvider) _viewer.getContentProvider(); 464 465 Object[] rootElements = contentProvider.getElements(_viewer.getInput()); 466 467 for (Object element : rootElements) { 468 assertTrue(tooltipProvider.getToolTipText(element).startsWith("ToolTip")); 469 } 470 } 471 } 472