Bug 577289 - tests for new large file associations preference

This change adds tests for then new preferences that handle opening
large files in specific editors.

Change-Id: I7fa69bca3f798a13009664b5213bbfcd4e0eab96
Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.ui/+/189775
Tested-by: Platform Bot <platform-bot@eclipse.org>
Tested-by: Andrey Loskutov <loskutov@gmx.de>
Reviewed-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/LargeFileAssociationsPreferencePage.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/LargeFileAssociationsPreferencePage.java
index 7d3d343..c5813c0 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/LargeFileAssociationsPreferencePage.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/ide/LargeFileAssociationsPreferencePage.java
@@ -222,9 +222,8 @@
 		} else {
 			createPreferencePageContents(pageComponent);
 		}
-		// TODO: are we adding help for this page?
-		// workbench.getHelpSystem().setHelp(parent,
-		// IWorkbenchHelpContextIds. ...);
+
+		//workbench.getHelpSystem().setHelp(parent, IWorkbenchHelpContextIds.LARGE_FILE_ASSOCIATIONS_PREFERENCE_PAGE);
 
 		return pageComponent;
 	}
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchHelpContextIds.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchHelpContextIds.java
index 29d29f1..2c05faf 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchHelpContextIds.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/IWorkbenchHelpContextIds.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2018 IBM Corporation and others.
+ * Copyright (c) 2000, 2022 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -220,6 +220,8 @@
 
 	String RESPONSIVE_UI = PREFIX + "responsive_ui_context"; //$NON-NLS-1$
 
+	String LARGE_FILE_ASSOCIATIONS_PREFERENCE_PAGE = PREFIX + "large_file_associations_preference_page_context"; //$NON-NLS-1$
+
 	// // Windows
 	String DETACHED_WINDOW = PREFIX + "detached_window_context"; //$NON-NLS-1$
 
diff --git a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LargeFileLimitsPreferenceHandler.java b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LargeFileLimitsPreferenceHandler.java
index 2ee599d..882a56b 100644
--- a/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LargeFileLimitsPreferenceHandler.java
+++ b/bundles/org.eclipse.ui.workbench/Eclipse UI/org/eclipse/ui/internal/LargeFileLimitsPreferenceHandler.java
@@ -73,6 +73,11 @@
 			this.editorId = editorId;
 			this.fileSize = fileSize;
 		}
+
+		@Override
+		public String toString() {
+			return '(' + editorId + ',' + fileSize + ')';
+		}
 	}
 
 	/**
@@ -80,6 +85,11 @@
 	 * choose an editor, with which to open the large document.
 	 */
 	public static final String PROMPT_EDITOR_PREFERENCE_VALUE = IPreferenceConstants.LARGE_FILE_LIMITS + "_prompt"; //$NON-NLS-1$
+	/**
+	 * Identifier of the preference page that allows the user to view and set file
+	 * limit associations.
+	 */
+	public static final String LARGE_FILE_ASSOCIATIONS_PREFERENCE_PAGE_ID = "org.eclipse.ui.preferencePages.LargeFileAssociations"; //$NON-NLS-1$
 
 	private static final IPreferenceStore PREFERENCE_STORE = PrefUtil.getInternalPreferenceStore();
 
@@ -94,17 +104,22 @@
 
 	private static final String EMPTY_VALUES = ""; //$NON-NLS-1$
 
-	private static final String LARGE_FILE_ASSOCIATIONS_PREFERENCE_PAGE_ID = "org.eclipse.ui.preferencePages.LargeFileAssociations"; //$NON-NLS-1$
 
 	private static final boolean DEFAULT_REMEMBER_EDITOR_SELECTION = false;
 
 	private final Map<String, List<FileLimit>> preferencesCache;
 	private final IPropertyChangeListener preferencesListener;
+	private final PromptForEditor promptForEditor;
 
 	private long legacyMaxFileSize = 0;
 	private boolean legacyCheckDocumentSize;
 
-	LargeFileLimitsPreferenceHandler() {
+	public LargeFileLimitsPreferenceHandler() {
+		this(new DialogPromptForEditor());
+	}
+
+	public LargeFileLimitsPreferenceHandler(PromptForEditor promptForEditor) {
+		this.promptForEditor = promptForEditor;
 		initLegacyPreference();
 		preferencesCache = new HashMap<>();
 		preferencesListener = e -> {
@@ -211,7 +226,7 @@
 	 *         large documents, or the editor ID specified by the preference or user
 	 *         for the given document type
 	 */
-	Optional<String> getEditorForInput(IEditorInput editorInput) {
+	public Optional<String> getEditorForInput(IEditorInput editorInput) {
 		if (editorInput instanceof IPathEditorInput) {
 			IPathEditorInput pathEditorInput = (IPathEditorInput) editorInput;
 			try {
@@ -247,20 +262,15 @@
 			isPromptPreferenceValue = isPromptPreferenceValue(fileLimit.editorId);
 		}
 		if (isPromptPreferenceValue) {
-			IEditorDescriptor editor = null;
-			Shell shell = ProgressManagerUtil.getDefaultParent();
-			LargeFileEditorSelectionDialog dialog = new LargeFileEditorSelectionDialog(shell, inputPath.getFileExtension(), fileLimit.fileSize);
-			dialog.setMessage(WorkbenchMessages.EditorManager_largeDocumentWarning);
-			if (dialog.open() == Window.OK) {
-				editor = dialog.getSelectedEditor();
-			}
+			promptForEditor.prompt(inputPath, fileLimit);
+			IEditorDescriptor editor = promptForEditor.getSelectedEditor();
 			if (editor == null) {
 				// the user pressed cancel in the editor selection dialog, indicate no editor
 				// should be open
 				return null;
 			}
 			editorId = editor.getId();
-			boolean rememberSelectedEditor = dialog.shouldRememberSelectedEditor();
+			boolean rememberSelectedEditor = promptForEditor.shouldRememberSelectedEditor();
 			if (editorId != null && rememberSelectedEditor) {
 				FileLimit newLimit = new FileLimit(editorId, fileLimit.fileSize);
 				replaceLimitForLargeFile(inputPath, fileLimit, newLimit);
@@ -400,7 +410,7 @@
 		return preferenceValues;
 	}
 
-	private static List<FileLimit> getLargeFilePreferenceValues(String fileExtension) {
+	public static List<FileLimit> getLargeFilePreferenceValues(String fileExtension) {
 		List<FileLimit> preferenceValues = new ArrayList<>();
 		String[] disabled = getDisabledExtensionTypes();
 		boolean isDisabled = Arrays.asList(disabled).contains(fileExtension);
@@ -516,7 +526,42 @@
 		dialog.open();
 	}
 
-	private static class LargeFileEditorSelectionDialog extends EditorSelectionDialog {
+	public interface PromptForEditor {
+
+		void prompt(IPath inputPath, FileLimit fileLimit);
+		IEditorDescriptor getSelectedEditor();
+		boolean shouldRememberSelectedEditor();
+	}
+
+	private static class DialogPromptForEditor implements PromptForEditor {
+
+		IEditorDescriptor selectedEditor = null;
+		boolean rememberSelection = false;
+
+		@Override
+		public void prompt(IPath inputPath, FileLimit fileLimit) {
+			Shell shell = ProgressManagerUtil.getDefaultParent();
+			LargeFileEditorSelectionDialog dialog =
+					new LargeFileEditorSelectionDialog(shell, inputPath.getFileExtension(), fileLimit.fileSize);
+			dialog.setMessage(WorkbenchMessages.EditorManager_largeDocumentWarning);
+			if (dialog.open() == Window.OK) {
+				selectedEditor = dialog.getSelectedEditor();
+				rememberSelection = dialog.shouldRememberSelectedEditor();
+			}
+		}
+
+		@Override
+		public IEditorDescriptor getSelectedEditor() {
+			return selectedEditor;
+		}
+
+		@Override
+		public boolean shouldRememberSelectedEditor() {
+			return rememberSelection;
+		}
+	}
+
+	public static class LargeFileEditorSelectionDialog extends EditorSelectionDialog {
 
 		private final String extension;
 		private final long fileSize;
@@ -524,7 +569,7 @@
 		private Button rememberSelectionButton;
 		private boolean rememberSelection = DEFAULT_REMEMBER_EDITOR_SELECTION;
 
-		LargeFileEditorSelectionDialog(Shell shell, String extension, long size) {
+		public LargeFileEditorSelectionDialog(Shell shell, String extension, long size) {
 			super(shell);
 			this.extension = extension;
 			this.fileSize = size;
@@ -570,7 +615,7 @@
 			return contents;
 		}
 
-		boolean shouldRememberSelectedEditor() {
+		public boolean shouldRememberSelectedEditor() {
 			return rememberSelection;
 		}
 	}
diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java
index c4538cf..c0da180 100644
--- a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java
+++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/internal/InternalTestSuite.java
@@ -14,6 +14,7 @@
  *******************************************************************************/
 package org.eclipse.ui.tests.internal;
 
+import org.eclipse.ui.tests.largefile.LargeFileLimitsPreferenceHandlerTest;
 import org.eclipse.ui.tests.markers.Bug75909Test;
 import org.eclipse.ui.tests.markers.DeclarativeFilterActivityTest;
 import org.eclipse.ui.tests.markers.DeclarativeFilterDeclarationTest;
@@ -61,5 +62,6 @@
 	SaveablesListTest.class,
 	Bug540297WorkbenchPageFindViewTest.class,
 	Bug549139Test.class,
+	LargeFileLimitsPreferenceHandlerTest.class,
 })
 public class InternalTestSuite {}
diff --git a/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/largefile/LargeFileLimitsPreferenceHandlerTest.java b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/largefile/LargeFileLimitsPreferenceHandlerTest.java
new file mode 100644
index 0000000..882e262
--- /dev/null
+++ b/tests/org.eclipse.ui.tests/Eclipse UI Tests/org/eclipse/ui/tests/largefile/LargeFileLimitsPreferenceHandlerTest.java
@@ -0,0 +1,529 @@
+/*******************************************************************************
+ * 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.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+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.ILogListener;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.jface.preference.PreferenceDialog;
+import org.eclipse.jface.preference.PreferencePage;
+import org.eclipse.jface.resource.ImageDescriptor;
+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.IPersistableElement;
+import org.eclipse.ui.IWorkbenchPage;
+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 TestPromptForEditor testPromptForEditor;
+	private LargeFileLimitsPreferenceHandler preferenceHandler;
+	private TestEditorInput testEditorInput;
+	private TestLogListener logListener;
+
+	public LargeFileLimitsPreferenceHandlerTest() {
+		super(LargeFileLimitsPreferenceHandlerTest.class.getSimpleName());
+	}
+
+	@Override
+	protected void doSetUp() throws Exception {
+		super.doSetUp();
+		testPromptForEditor = new TestPromptForEditor();
+		preferenceHandler = new LargeFileLimitsPreferenceHandler(testPromptForEditor);
+		testEditorInput = new TestEditorInput();
+		logListener = new TestLogListener();
+		Platform.addLogListener(logListener);
+	}
+
+	@Override
+	protected void doTearDown() throws Exception {
+		try {
+			Platform.removeLogListener(logListener);
+			setDefaultPreferences();
+			preferenceHandler.dispose();
+			testEditorInput.dispose();
+		} finally {
+			super.doTearDown();
+		}
+	}
+
+	@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 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);
+		assertFalse("Expected no editor for large file of type: " + TXT_EXTENSION, editorForInput.isPresent());
+	}
+
+	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 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;
+		}
+	}
+
+	private static class TestEditorInput implements IPathEditorInput {
+
+		private final Path temporaryFile;
+
+		TestEditorInput() throws IOException {
+			temporaryFile = Files.createTempFile("test_file", "." + TXT_EXTENSION);
+			Files.write(temporaryFile, Arrays.asList("some line 1", "some line 2"));
+		}
+
+		void dispose() throws IOException {
+			Files.delete(temporaryFile);
+		}
+
+		@Override
+		public boolean exists() {
+			return true;
+		}
+
+		@Override
+		public ImageDescriptor getImageDescriptor() {
+			return null;
+		}
+
+		@Override
+		public String getName() {
+			return "test editor input";
+		}
+
+		@Override
+		public IPersistableElement getPersistable() {
+			return null;
+		}
+
+		@Override
+		public String getToolTipText() {
+			return getName();
+		}
+
+		@Override
+		public <T> T getAdapter(Class<T> adapter) {
+			return null;
+		}
+
+		@Override
+		public IPath getPath() {
+			return new org.eclipse.core.runtime.Path(temporaryFile.toString());
+		}
+
+	}
+}
diff --git a/tests/org.eclipse.ui.tests/plugin.xml b/tests/org.eclipse.ui.tests/plugin.xml
index 618bd3a..dc8be65 100644
--- a/tests/org.eclipse.ui.tests/plugin.xml
+++ b/tests/org.eclipse.ui.tests/plugin.xml
@@ -840,6 +840,16 @@
                contentTypeId="org.eclipse.ui.tests.contentType.bug516470-witheditor">
          </contentTypeBinding>
       </editor>
+      <editor
+            name="Test Editor 1 For Large File Associations"
+            default="false"
+            id="org.eclipse.ui.tests.largefile.testeditor1">
+      </editor>
+      <editor
+            name="Test Editor 2 For Large File Associations"
+            default="false"
+            id="org.eclipse.ui.tests.largefile.testeditor2">
+      </editor>
    </extension>
    <extension
          point="org.eclipse.ui.actionSets">