| /******************************************************************************* |
| * Copyright (c) 2017, 2018 Red Hat Inc. and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Lucas Bullen - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.tests.dialogs; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.InputStream; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IFolder; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.jface.text.Position; |
| import org.eclipse.swt.custom.StyleRange; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog; |
| import org.eclipse.ui.tests.harness.util.DisplayHelper; |
| import org.eclipse.ui.tests.harness.util.UITestCase; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.JUnit4; |
| |
| /** |
| * Tests that resources are highlighted to match user search input. See Bug |
| * 519525, 520250, and 520251 for references. |
| * |
| * @since 3.14 |
| */ |
| @RunWith(JUnit4.class) |
| public class ResourceItemLabelTest extends UITestCase { |
| |
| /** |
| * Constructs a new instance of <code>ResourceItemlLabelTest</code>. |
| */ |
| |
| public ResourceItemLabelTest() { |
| super(ResourceItemLabelTest.class.getSimpleName()); |
| } |
| |
| private IProject project; |
| |
| @Override |
| protected void doSetUp() throws Exception { |
| super.doSetUp(); |
| project = ResourcesPlugin.getWorkspace().getRoot() |
| .getProject(getClass().getName() + "_" + System.currentTimeMillis()); |
| project.create(new NullProgressMonitor()); |
| project.open(new NullProgressMonitor()); |
| } |
| |
| /** |
| * Tests that the highlighting matches basic substrings |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testSubstringMatch() throws Exception { |
| Position[] atBeginning = { new Position(0, 2) }; |
| compareStyleRanges(atBeginning, getStyleRanges("te", "test.txt"), "test.txt", ""); |
| |
| Position[] full = { new Position(0, 8) }; |
| compareStyleRanges(full, getStyleRanges("test.txt", "test.txt"), "test.txt", ""); |
| |
| Position[] withDigits = { new Position(0, 3) }; |
| compareStyleRanges(withDigits, getStyleRanges("t3s", "t3st.txt"), "t3st.txt", ""); |
| } |
| |
| /** |
| * Tests that the highlighting matches CamelCase searches |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testCamelCaseMatch() throws Exception { |
| Position[] atBeginning = { new Position(0, 1), new Position(4, 1) }; |
| compareStyleRanges(atBeginning, getStyleRanges("TT", "ThisTest.txt"), "ThisTest.txt", ""); |
| |
| Position[] nextToEachother = { new Position(0, 1), new Position(4, 2) }; |
| compareStyleRanges(nextToEachother, getStyleRanges("TAT", "ThisATest.txt"), "ThisATest.txt", ""); |
| |
| Position[] withSubstrings = { new Position(0, 2), new Position(4, 2) }; |
| compareStyleRanges(withSubstrings, getStyleRanges("ThTe", "ThisTest.txt"), "ThisTest.txt", ""); |
| |
| Position[] withDigits = { new Position(0, 2), new Position(4, 2) }; |
| compareStyleRanges(withDigits, getStyleRanges("Th3T", "This3Test.txt"), "This3Test.txt", ""); |
| |
| Position[] skippingDigit = { new Position(0, 2), new Position(5, 1) }; |
| compareStyleRanges(skippingDigit, getStyleRanges("ThT", "This3Test.txt"), "This3Test.txt", ""); |
| } |
| |
| /** |
| * Tests that the highlighting matches searches using '*' and '?' |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testPatternMatch() throws Exception { |
| Position[] questionMark = { new Position(0, 1), new Position(2, 2) }; |
| compareStyleRanges(questionMark, getStyleRanges("t?st", "test.txt"), "test.txt", ""); |
| |
| Position[] star = { new Position(0, 1), new Position(6, 2) }; |
| compareStyleRanges(star, getStyleRanges("t*xt", "test.txt"), "test.txt", ""); |
| |
| Position[] both = { new Position(0, 1), new Position(2, 1), new Position(6, 2) }; |
| compareStyleRanges(both, getStyleRanges("t?s*xt", "test.txt"), "test.txt", ""); |
| |
| Position[] withDigits = { new Position(0, 1), new Position(2, 2), new Position(7, 3) }; |
| compareStyleRanges(withDigits, getStyleRanges("t?s3*x3t", "tes3t.tx3t"), "tes3t.tx3t", ""); |
| } |
| |
| /** |
| * Tests that regex symbols do not break search |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testBug529451() throws Exception { |
| Position[] basic = { new Position(4, 1) }; |
| compareStyleRanges(basic, getStyleRanges("*$", "test$.txt"), "test$.txt", ""); |
| |
| Position[] multiple = { new Position(0, 3), new Position(7, 6), new Position(14, 1) }; |
| compareStyleRanges(multiple, getStyleRanges("^${*}[])(+?-", "^${skip}[])(+s-"), "^${skip}[])(+s-", ""); |
| } |
| |
| /** |
| * Tests that the highlighting matches searches using '>' and ' ' |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testDisableAutoPrefixMatching() throws Exception { |
| Position[] questionMark = { new Position(0, 1), new Position(4, 4) }; |
| compareStyleRanges(questionMark, getStyleRanges("M*file<", "Makefile"), "Makefile", ""); |
| |
| Position[] star = { new Position(0, 1), new Position(4, 4) }; |
| compareStyleRanges(star, getStyleRanges("M*file ", "MockFile"), "MockFile", ""); |
| |
| Position[] both = { new Position(0, 3), new Position(6, 1) }; |
| compareStyleRanges(both, getStyleRanges("CreS<", "CreateStuff.java"), "CreateStuff.java", ""); |
| } |
| |
| /** |
| * Tests that the highlighting matches extension searches |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testExtensionMatch() throws Exception { |
| Position[] basic = { new Position(8, 3) }; |
| compareStyleRanges(basic, getStyleRanges(".MF", "MANIFEST.MF"), "MANIFEST.MF", ""); |
| |
| Position[] withSubstring = { new Position(0, 1), new Position(8, 3) }; |
| compareStyleRanges(withSubstring, getStyleRanges("M.MF", "MANIFEST.MF"), "MANIFEST.MF", ""); |
| |
| Position[] withCamelCase = { new Position(4, 3), new Position(8, 1) }; |
| compareStyleRanges(withCamelCase, getStyleRanges(".TxT", "test.TxxT"), "test.TxxT", ""); |
| |
| Position[] withPattern = { new Position(4, 2), new Position(8, 1) }; |
| compareStyleRanges(withPattern, getStyleRanges(".t*t", "test.txxt"), "test.txxt", ""); |
| |
| Position[] withDigits = { new Position(4, 2), new Position(8, 1) }; |
| compareStyleRanges(withDigits, getStyleRanges(".3*3", "test.3xx3"), "test.3xx3", ""); |
| } |
| |
| /** |
| * Tests for Bug 528301: Camel Case match with precursing letter matches |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testBug528301() throws Exception { |
| Position[] withSameLettersBeforeCamel = { new Position(0, 1), new Position(3, 1), new Position(5, 1) }; |
| compareStyleRanges(withSameLettersBeforeCamel, getStyleRanges("ABC", "AbcBzCz.txt"), "AbcBzCz.txt", ""); |
| |
| Position[] withDigits = { new Position(0, 1), new Position(4, 1), new Position(6, 1), new Position(8, 1) }; |
| compareStyleRanges(withDigits, getStyleRanges("AB5C", "Ab5cBz5zCz.txt"), "Ab5cBz5zCz.txt", ""); |
| } |
| |
| /** |
| * Tests for Bug 531610: Open Resource dialog doesn't show paths for duplicated |
| * files |
| * |
| * @throws Exception |
| */ |
| @Test |
| public void testBug531610() throws Exception { |
| IFolder folder = project.getFolder("folder"); |
| IFile fileB = folder.getFile("file"); |
| folder.create(true, true, new NullProgressMonitor()); |
| fileB.create(stream, true, new NullProgressMonitor()); |
| StyleRange[] ranges = getStyleRanges("file", "file"); |
| // if true adds "/folder" length to the range |
| boolean withFolder = false; |
| for (StyleRange range : ranges) { |
| if (range.length > 3 + project.getName().length()) { |
| withFolder = true; |
| } |
| } |
| Position[] withDigits = { new Position(0, 4) }; // " - " |
| // withFolder - "/folder" |
| compareStyleRanges(withDigits, ranges, "file", withFolder ? "/folder" : ""); |
| } |
| |
| /** |
| * Test for Bug 566858 - java.lang.StringIndexOutOfBoundsException in |
| * FilteredResourcesSelectionDialog with leading whitespace in resource names |
| */ |
| @Test |
| public void testBug566858_leadingWhitespace() throws Exception { |
| Position[] pos = new Position[] { new Position(0, 5) }; |
| compareStyleRanges(pos, getStyleRanges(" test", " test.txt"), " test.txt", ""); |
| |
| pos = new Position[] { new Position(1, 4) }; |
| compareStyleRanges(pos, getStyleRanges("?test", " test.txt"), " test.txt", ""); |
| |
| pos = new Position[] { new Position(5, 4) }; |
| compareStyleRanges(pos, getStyleRanges("*.txt", " test.txt"), " test.txt", ""); |
| } |
| |
| private void compareStyleRanges(Position[] expected, StyleRange[] actual, String fileName, String fileParentPath) { |
| assertEquals("Length of StyleRanges is incorrect: " + printStyleRanges(actual), expected.length + 1, |
| actual.length); |
| int i; |
| for (i = 0; i < actual.length - 1; i++) { |
| assertEquals("Start of StyleRange at index " + i + " is incorrect.", expected[i].offset, actual[i].start); |
| assertEquals("Length of StyleRange at index " + i + " is incorrect.", expected[i].length, actual[i].length); |
| } |
| assertEquals("Start of file path StyleRange is incorrect.", fileName.length(), actual[i].start); |
| assertEquals("Length of file path StyleRange at index is incorrect.", |
| 3 + project.getName().length() + fileParentPath.length(), actual[i].length); |
| } |
| |
| private FilteredResourcesSelectionDialog dialog; |
| private static InputStream stream = new ByteArrayInputStream(new byte[0]); |
| |
| private StyleRange[] getStyleRanges(String searchString, String fileName) throws Exception { |
| IFile file = project.getFile(fileName); |
| file.create(stream, true, new NullProgressMonitor()); |
| project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor()); |
| |
| dialog = new FilteredResourcesSelectionDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), |
| true, project, |
| IResource.FILE); |
| dialog.setBlockOnOpen(false); |
| dialog.create(); |
| dialog.open(); |
| Shell shell = dialog.getShell(); |
| |
| new DisplayHelper() { |
| @Override |
| protected boolean condition() { |
| return project.getFile(fileName).exists(); |
| } |
| }.waitForCondition(shell.getDisplay(), 1000); |
| |
| assertTrue("File was not created", project.getFile(fileName).exists()); |
| dialog.reloadCache(true, new NullProgressMonitor()); |
| |
| ((Text) dialog.getPatternControl()).setText(searchString); |
| Table table = (Table) ((Composite) ((Composite) ((Composite) shell.getChildren()[0]).getChildren()[0]) |
| .getChildren()[0]).getChildren()[3]; |
| |
| new DisplayHelper() { |
| @Override |
| protected boolean condition() { |
| return table.getItemCount() > 0; |
| } |
| }.waitForCondition(shell.getDisplay(), 3000); |
| |
| Object data = table.getItem(0).getData("org.eclipse.jfacestyled_label_key_0"); |
| |
| dialog.close(); |
| file.delete(true, null); |
| if (data == null || !(data instanceof StyleRange[])) { |
| fail("No StyleRanges found for the TableItem"); |
| } |
| |
| return (StyleRange[]) data; |
| } |
| |
| private String printStyleRanges(StyleRange[] styleRanges) { |
| if (styleRanges == null) { |
| return "null"; |
| } |
| if (styleRanges.length == 0) { |
| return "[]"; |
| } |
| StringBuilder builder = new StringBuilder(); |
| builder.append('['); |
| for (StyleRange range : styleRanges) { |
| builder.append("{start: "); |
| builder.append(range.start); |
| builder.append(", length: "); |
| builder.append(range.length); |
| builder.append("}, "); |
| } |
| builder.setLength(builder.length() - 2); |
| builder.append(']'); |
| return builder.toString(); |
| } |
| |
| @Override |
| protected void doTearDown() throws Exception { |
| if (dialog != null) { |
| dialog.close(); |
| } |
| if (project != null) { |
| project.delete(true, null); |
| } |
| super.doTearDown(); |
| } |
| } |