blob: fa617eeaba37e0bd324a7caab94b006a2a01a493 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2022 Simeon Andreev 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:
* Simeon Andreev - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.tests.largefile;
import static org.junit.Assert.assertArrayEquals;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.ILogListener;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorRegistry;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.internal.LargeFileLimitsPreferenceHandler;
import org.eclipse.ui.internal.LargeFileLimitsPreferenceHandler.FileLimit;
import org.eclipse.ui.internal.LargeFileLimitsPreferenceHandler.LargeFileEditorSelectionDialog;
import org.eclipse.ui.internal.LargeFileLimitsPreferenceHandler.PromptForEditor;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.tests.harness.util.UITestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Tests for the large file associations preference added for bug 577289.
*
* @since 3.5
*
*/
@RunWith(JUnit4.class)
public class LargeFileLimitsPreferenceHandlerTest extends UITestCase {
public static final String TEST_EDITOR_ID1 = "org.eclipse.ui.tests.largefile.testeditor1";
public static final String TEST_EDITOR_ID2 = "org.eclipse.ui.tests.largefile.testeditor2";
private static final int DEFALT_LIMIT_VALUE = 8 * 1024 * 1024;
private static final String TXT_EXTENSION = "txt";
private static final String XML_EXTENSION = "xml";
private final IProgressMonitor monitor;
private IProject testProject;
private IFile temporaryFile;
private TestPromptForEditor testPromptForEditor;
private LargeFileLimitsPreferenceHandler preferenceHandler;
private IEditorInput testEditorInput;
private TestLogListener logListener;
public LargeFileLimitsPreferenceHandlerTest() {
super(LargeFileLimitsPreferenceHandlerTest.class.getSimpleName());
monitor = new NullProgressMonitor();
}
@Override
protected void doSetUp() throws Exception {
super.doSetUp();
createTestFile();
testPromptForEditor = new TestPromptForEditor();
preferenceHandler = new LargeFileLimitsPreferenceHandler(testPromptForEditor);
testEditorInput = new FileEditorInput(temporaryFile);
logListener = new TestLogListener();
Platform.addLogListener(logListener);
}
private void createTestFile() throws CoreException {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot workspaceRoot = workspace.getRoot();
testProject = workspaceRoot.getProject("SomeProject");
testProject.create(monitor);
testProject.open(monitor);
IPath path = new Path("/" + testProject.getName() + "/test_file" + "." + TXT_EXTENSION);
temporaryFile = workspaceRoot.getFile(path);
String content = String.join(System.lineSeparator(), "some line 1", "some line 2");
boolean force = true;
temporaryFile.create(new ByteArrayInputStream(content.getBytes()), force, monitor);
}
@Override
protected void doTearDown() throws Exception {
try {
Platform.removeLogListener(logListener);
setDefaultPreferences();
preferenceHandler.dispose();
deleteTestFile();
boolean save = false;
closeAllEditors(save);
} finally {
super.doTearDown();
}
}
private void deleteTestFile() throws CoreException {
boolean force = true;
temporaryFile.delete(force, monitor);
testProject.delete(force, monitor);
}
@Test
public void testPreferencePageSmokeTest() throws Throwable {
String pageId = LargeFileLimitsPreferenceHandler.LARGE_FILE_ASSOCIATIONS_PREFERENCE_PAGE_ID;
Shell shell = getWorkbench().getActiveWorkbenchWindow().getShell();
PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn(shell, pageId, null, null);
try {
waitForJobs();
dialog.setBlockOnOpen(false);
dialog.open();
waitForJobs();
PreferencePage page = (PreferencePage) dialog.getSelectedPage();
// close
page.performOk();
waitForJobs();
} finally {
dialog.close();
logListener.assertNoLoggedErrors();
}
}
@Test
public void testEditorPromptDialogSmokeTest() throws Throwable {
boolean closedDialog = false;
long fileSize = 4L;
Shell shell = getWorkbench().getActiveWorkbenchWindow().getShell();
LargeFileEditorSelectionDialog dialog = new LargeFileEditorSelectionDialog(shell, TXT_EXTENSION, fileSize);
try {
waitForJobs();
dialog.setBlockOnOpen(false);
dialog.open();
waitForJobs();
dialog.close();
closedDialog = true;
IEditorDescriptor selectedEditor = dialog.getSelectedEditor();
boolean rememberSelection = dialog.shouldRememberSelectedEditor();
assertNull("Expected no default selection in dialog", selectedEditor);
assertFalse("Expected default to not remember editor selection", rememberSelection);
waitForJobs();
} finally {
if (!closedDialog) {
dialog.close();
}
logListener.assertNoLoggedErrors();
}
}
@Test
public void testOpenEditorWithIgnoreSize() throws Exception {
String testEditorId = TEST_EDITOR_ID2;
long fileSize = 4L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId, fileSize));
configureFileLimits(fileLimits);
Class<?> expectedEditorClass = org.eclipse.ui.tests.api.MockEditorPart.class;
IEditorInput editorInput = testEditorInput;
String editorIdForOpen = "org.eclipse.ui.tests.api.MockEditorPart1";
IWorkbenchPage page = getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart editor = null;
try {
boolean activate = true;
int flags = IWorkbenchPage.MATCH_NONE | IWorkbenchPage.MATCH_IGNORE_SIZE;
editor = page.openEditor(editorInput, editorIdForOpen, activate, flags);
assertEquals("Wrong editor opened", expectedEditorClass, editor.getClass());
} finally {
if (editor != null) {
editor.dispose();
}
}
}
@Test
public void testDisabledDefaultLimit() throws Exception {
String testEditorId = "org.eclipse.ui.tests.api.MockEditorPart1";
long fileSize = 1L;
LargeFileLimitsPreferenceHandler.setDefaultLimit(fileSize);
LargeFileLimitsPreferenceHandler.disableDefaultLimit();
IEditorRegistry editorRegistry = getWorkbench().getEditorRegistry();
IEditorDescriptor testEditor = editorRegistry.findEditor(testEditorId);
assertNotNull("Expected to find editor with ID: " + testEditorId, testEditor);
testPromptForEditor.selectedEditor = testEditor;
testPromptForEditor.rememberSelection = false;
// bug 579119: dialog to chose editor should not come up, we disabled the
// default limit preference
assertNoEditorIsChosen();
}
@Test
public void testOpenEditor() throws Exception {
String testEditorId = "org.eclipse.ui.tests.api.MockEditorPart1";
long fileSize = 4L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId, fileSize));
configureFileLimits(fileLimits);
Class<?> expectedEditorClass = org.eclipse.ui.tests.api.MockEditorPart.class;
IEditorInput editorInput = testEditorInput;
String editorIdForOpen = TEST_EDITOR_ID2;
IWorkbenchPage page = getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart editor = null;
try {
editor = page.openEditor(editorInput, editorIdForOpen);
assertEquals("Wrong editor opened", expectedEditorClass, editor.getClass());
} finally {
if (editor != null) {
editor.dispose();
}
}
}
@Test
public void testOpenFileFromDeletedProject() throws Exception {
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot root = workspace.getRoot();
String projectName = LargeFileLimitsPreferenceHandlerTest.class.getSimpleName() + "TestProject";
IProject project = root.getProject(projectName);
assertFalse("Expected project to not exist yet: " + projectName, project.exists());
NullProgressMonitor monitor = new NullProgressMonitor();
project.create(monitor);
project.open(monitor);
assertTrue("Expected project to be accessible: " + projectName, project.isAccessible());
assertTrue("Expected project to exist: " + projectName, project.exists());
IFile testFile = project.getFile("test_file.txt");
ByteArrayInputStream input = new ByteArrayInputStream("test contents".getBytes());
boolean force = true;
testFile.create(input, force, monitor);
IPathEditorInput editorInput = new FileEditorInput(testFile);
project.delete(force, monitor);
waitForJobs();
String testEditorId = "org.eclipse.ui.tests.api.MockEditorPart1";
long fileSize = 4L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId, fileSize));
configureFileLimits(fileLimits);
// we expect the "error editor" to be opened here, as the file we want to open was deleted
Class<?> expectedEditorClass = org.eclipse.ui.internal.ErrorEditorPart.class;
String editorIdForOpen = TEST_EDITOR_ID2;
IWorkbenchPage page = getWorkbench().getActiveWorkbenchWindow().getActivePage();
IEditorPart editor = null;
try {
editor = page.openEditor(editorInput, editorIdForOpen);
assertEquals("Wrong editor opened", expectedEditorClass, editor.getClass());
} finally {
if (editor != null) {
editor.dispose();
}
}
}
@Test
public void testRestoreDefaults() throws Exception {
String[] configuredExtensions = { TXT_EXTENSION, XML_EXTENSION };
String[] disabledExtensions = { XML_EXTENSION };
LargeFileLimitsPreferenceHandler.setConfiguredExtensionTypes(configuredExtensions);
LargeFileLimitsPreferenceHandler.setDisabledExtensionTypes(disabledExtensions);
long fileSize = 4L;
LargeFileLimitsPreferenceHandler.setDefaultLimit(fileSize);
String testEditorId1 = TEST_EDITOR_ID1;
long fileSize1 = 4_000L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId1, fileSize1));
configureFileLimits(fileLimits);
LargeFileLimitsPreferenceHandler.restoreDefaults();
doTestDefaults();
}
@Test
public void testDefaults() throws Exception {
doTestDefaults();
}
@Test
public void testSetConfiguredExtensions() throws Exception {
String[] extensions = { TXT_EXTENSION, XML_EXTENSION };
LargeFileLimitsPreferenceHandler.setConfiguredExtensionTypes(extensions);
String[] configuredExtensions = LargeFileLimitsPreferenceHandler.getConfiguredExtensionTypes();
assertArrayEquals("Wrong configured extensions", extensions, configuredExtensions);
}
@Test
public void testSetDisabledExtensions() throws Exception {
String[] extensions = { TXT_EXTENSION, XML_EXTENSION };
LargeFileLimitsPreferenceHandler.setDisabledExtensionTypes(extensions);
String[] configuredExtensions = LargeFileLimitsPreferenceHandler.getDisabledExtensionTypes();
assertArrayEquals("Wrong disabled extensions", extensions, configuredExtensions);
}
@Test
public void testGetEditorForInput() throws Exception {
long fileSize = 4L;
LargeFileLimitsPreferenceHandler.setDefaultLimit(fileSize);
String testEditorId = TEST_EDITOR_ID1;
IEditorRegistry editorRegistry = getWorkbench().getEditorRegistry();
IEditorDescriptor testEditor = editorRegistry.findEditor(testEditorId);
assertNotNull("Expected to find editor with ID: " + testEditorId, testEditor);
testPromptForEditor.selectedEditor = testEditor;
testPromptForEditor.rememberSelection = false;
assertEditorIsChosen(testEditorId);
List<FileLimit> limits = LargeFileLimitsPreferenceHandler.getLargeFilePreferenceValues(TXT_EXTENSION);
assertEquals("Expected exactly 1 file limit to be set, but got: " + limits, 1, limits.size());
FileLimit limit = limits.get(0);
assertEquals("Wrong limit editor ID",
LargeFileLimitsPreferenceHandler.PROMPT_EDITOR_PREFERENCE_VALUE, limit.editorId);
assertEquals("Wrong limit file size", fileSize, limit.fileSize);
}
@Test
public void testRememberSelection() throws Exception {
long fileSize = 4L;
LargeFileLimitsPreferenceHandler.setDefaultLimit(fileSize);
String testEditorId = TEST_EDITOR_ID1;
IEditorRegistry editorRegistry = getWorkbench().getEditorRegistry();
IEditorDescriptor testEditor = editorRegistry.findEditor(testEditorId);
assertNotNull("Expected to find editor with ID: " + testEditorId, testEditor);
testPromptForEditor.selectedEditor = testEditor;
testPromptForEditor.rememberSelection = true;
assertEditorIsChosen(testEditorId);
List<FileLimit> limits = LargeFileLimitsPreferenceHandler.getLargeFilePreferenceValues(TXT_EXTENSION);
assertEquals("Expected exactly 1 file limit to be set: " + limits, 1, limits.size());
FileLimit limit = limits.get(0);
assertEquals("Wrong limit editor ID remembered", testEditorId, limit.editorId);
assertEquals("Wrong limit file size remembered", fileSize, limit.fileSize);
}
@Test
public void testNoConfiguration() throws Exception {
assertNoEditorIsChosen();
}
@Test
public void testDefaultLimit() throws Exception {
long fileSize = 4L;
LargeFileLimitsPreferenceHandler.setDefaultLimit(fileSize);
List<FileLimit> limits = LargeFileLimitsPreferenceHandler.getLargeFilePreferenceValues(TXT_EXTENSION);
assertEquals("Expected only default file limit, but got: " + limits, 1, limits.size());
FileLimit defaultLimit = limits.get(0);
assertEquals("Wrong editor ID",
LargeFileLimitsPreferenceHandler.PROMPT_EDITOR_PREFERENCE_VALUE, defaultLimit.editorId);
assertEquals("Wrong file size limit", fileSize, defaultLimit.fileSize);
}
@Test
public void testSingleLimitForExtension() throws Exception {
String testEditorId = TEST_EDITOR_ID1;
long fileSize = 4L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId, fileSize));
configureFileLimits(fileLimits);
assertEditorIsChosen(testEditorId);
}
@Test
public void testMultipleLimitsForExtension() throws Exception {
String testEditorId1 = TEST_EDITOR_ID1;
long fileSize1 = 4L;
String testEditorId2 = TEST_EDITOR_ID2;
long fileSize2 = 8L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId1, fileSize1), new FileLimit(testEditorId2, fileSize2));
configureFileLimits(fileLimits);
// editor for largest matching file limit should be chosen
assertEditorIsChosen(testEditorId2);
}
@Test
public void testNoMatchingLimit() throws Exception {
String testEditorId1 = TEST_EDITOR_ID1;
long fileSize1 = 4_000L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId1, fileSize1));
configureFileLimits(fileLimits);
assertNoEditorIsChosen();
}
@Test
public void testSingleFileLimitAndDefault() throws Exception {
long defaultLimit = 4L;
LargeFileLimitsPreferenceHandler.setDefaultLimit(defaultLimit);
String testEditorId = TEST_EDITOR_ID1;
long fileSize = 1L;
List<FileLimit> fileLimits = Arrays.asList(new FileLimit(testEditorId, fileSize));
configureFileLimits(fileLimits);
assertEditorIsChosen(testEditorId);
}
private void doTestDefaults() {
String[] configuredExtensionTypes = LargeFileLimitsPreferenceHandler.getConfiguredExtensionTypes();
assertEmptyArray("Expected no large file associations to be configured by default", configuredExtensionTypes);
String[] disabledExtensionTypes = LargeFileLimitsPreferenceHandler.getDisabledExtensionTypes();
assertEmptyArray("Expected no large file associations to be disabled by default", disabledExtensionTypes);
String extension = TXT_EXTENSION;
List<FileLimit> limits = LargeFileLimitsPreferenceHandler.getFileLimitsForExtension(extension);
assertEquals("Expected no limit to be configured per default for file of type: " + extension,
Collections.EMPTY_LIST, limits);
boolean defaultLimitEnabled = LargeFileLimitsPreferenceHandler.isDefaultLimitEnabled();
assertFalse("Expected default large file limit to be disabled", defaultLimitEnabled);
long defaultLimit = LargeFileLimitsPreferenceHandler.getDefaultLimit();
assertEquals("Wrong default large file limit value", DEFALT_LIMIT_VALUE, defaultLimit);
}
private void assertNoEditorIsChosen() {
Optional<String> editorForInput = preferenceHandler.getEditorForInput(testEditorInput);
assertNotNull("Expected non-null result for large file of type: " + TXT_EXTENSION, editorForInput);
if (editorForInput.isPresent()) {
fail("Expected no editor for large file of type: " + TXT_EXTENSION + ", but got: " + editorForInput.get());
}
}
private void assertEditorIsChosen(String testEditorId) {
Optional<String> editorForInput = preferenceHandler.getEditorForInput(testEditorInput);
assertTrue("Expected editor for large file of type: " + TXT_EXTENSION, editorForInput.isPresent());
assertEquals("Wrong editor for large file", testEditorId, editorForInput.get());
}
private static void waitForJobs() {
waitForJobs(250, 2_000);
}
private static void setDefaultPreferences() {
LargeFileLimitsPreferenceHandler.setConfiguredExtensionTypes(new String[0]);
LargeFileLimitsPreferenceHandler.setDisabledExtensionTypes(new String[0]);
configureFileLimits(Collections.EMPTY_LIST);
LargeFileLimitsPreferenceHandler.setDefaultLimit(DEFALT_LIMIT_VALUE);
LargeFileLimitsPreferenceHandler.disableDefaultLimit();
}
private static void configureFileLimits(List<FileLimit> fileLimits) {
LargeFileLimitsPreferenceHandler.setFileLimitsForExtension(TXT_EXTENSION, fileLimits);
LargeFileLimitsPreferenceHandler.setFileLimitsForExtension(XML_EXTENSION, fileLimits);
}
private static void assertEmptyArray(String failMessage, String[] configuredExtensionTypes) {
assertEquals(failMessage, Collections.EMPTY_LIST, Arrays.asList(configuredExtensionTypes));
}
private static void closeAllEditors(boolean save) {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeAllEditors(save);
}
private static class TestLogListener implements ILogListener {
private final List<IStatus> errors = new ArrayList<>();
@Override
public void logging(IStatus status, String plugin) {
if (status.getSeverity() == IStatus.ERROR) {
errors.add(status);
}
}
void assertNoLoggedErrors() {
if (!errors.isEmpty()) {
StringBuilder failMessage = new StringBuilder();
failMessage.append("Unexpected logged errors:");
failMessage.append(System.lineSeparator());
for (IStatus error : errors) {
failMessage.append("Status message:");
failMessage.append(error.getMessage());
failMessage.append(System.lineSeparator());
failMessage.append("From plug-in:");
failMessage.append(error.getPlugin());
failMessage.append(System.lineSeparator());
Throwable exception = error.getException();
if (exception != null) {
failMessage.append("Exception:");
failMessage.append(System.lineSeparator());
failMessage.append(exception.getMessage());
failMessage.append(System.lineSeparator());
StackTraceElement[] stackTrace = exception.getStackTrace();
for (StackTraceElement element : stackTrace) {
failMessage.append('\t');
failMessage.append(element);
failMessage.append(System.lineSeparator());
}
}
}
fail(failMessage.toString());
}
}
}
private static class TestPromptForEditor implements PromptForEditor {
IEditorDescriptor selectedEditor = null;
boolean rememberSelection = false;
@Override
public void prompt(IPath inputPath, FileLimit fileLimit) {
// "selected" editor is set by tests
}
@Override
public IEditorDescriptor getSelectedEditor() {
return selectedEditor;
}
@Override
public boolean shouldRememberSelectedEditor() {
return rememberSelection;
}
}
}