blob: a0112b2eb158170eed98fb951bf0d079d50c1c39 [file] [log] [blame]
/*******************************************************************************
* 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 '&gt;' 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();
}
}