blob: 5a06d6b11d444d4016b45662953309701a691fb2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2013 Tasktop Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tasktop Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.mylyn.context.tests;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.util.Arrays;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.mylyn.commons.sdk.util.CommonTestUtil;
import org.eclipse.mylyn.commons.sdk.util.UiTestUtil;
import org.eclipse.mylyn.context.core.IInteractionContext;
import org.eclipse.mylyn.internal.context.core.InteractionContext;
import org.eclipse.mylyn.internal.context.core.InteractionContextScaling;
import org.eclipse.mylyn.internal.context.ui.state.ContextState;
import org.eclipse.mylyn.internal.context.ui.state.EditorStateParticipant;
import org.eclipse.mylyn.internal.monitor.ui.MonitorUiPlugin;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorDescriptor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IMemento;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.XMLMemento;
import org.eclipse.ui.internal.WorkbenchPage;
import org.eclipse.ui.part.FileEditorInput;
import junit.framework.TestCase;
/**
* @author Steffen Pingel
*/
public class EditorStateParticipantTest extends TestCase {
private final class MyEditorStateParticipant extends EditorStateParticipant {
// make visible
@Override
protected boolean is_3_x() {
return super.is_3_x();
}
@Override
protected void saveEditors_e_3_x(WorkbenchPage page, IMemento memento) throws Exception {
if (exceptionOnSave != null) {
throw exceptionOnSave;
}
super.saveEditors_e_3_x(page, memento);
}
@Override
protected void saveEditors_e_8_2(IWorkbenchPage page, IMemento memento) throws Exception {
if (exceptionOnSave != null) {
throw exceptionOnSave;
}
super.saveEditors_e_8_2(page, memento);
}
@Override
protected void saveEditors_e_4_legacy(WorkbenchPage page, IMemento memento) throws Exception {
if (exceptionOnSave != null) {
throw exceptionOnSave;
}
super.saveEditors_e_4_legacy(page, memento);
}
}
private final IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
private IProject project;
private IFile fileA;
private IFile fileB;
private MyEditorStateParticipant participant;
private Exception exceptionOnSave;
@Override
protected void setUp() throws Exception {
participant = new MyEditorStateParticipant();
assertTrue(participant.isEnabled());
}
@Override
protected void tearDown() throws Exception {
UiTestUtil.closeAllEditors();
if (project != null) {
project.delete(true, null);
}
}
public void testSaveState() {
XMLMemento memento = XMLMemento.createWriteRoot("State");
IInteractionContext context = new InteractionContext("id", new InteractionContextScaling());
ContextState state = new ContextState(context, context.getHandleIdentifier(), memento);
participant.saveState(state, true);
assertNotNull(memento.getChild(EditorStateParticipant.MEMENTO_EDITORS));
}
public void testSaveRestore() throws Exception {
createFilesAndOpenEditors();
XMLMemento memento = XMLMemento.createWriteRoot("State");
IInteractionContext context = new InteractionContext("id", new InteractionContextScaling());
ContextState state = new ContextState(context, context.getHandleIdentifier(), memento);
participant.saveState(state, true);
System.err.println(toString((XMLMemento) state.getMemento(EditorStateParticipant.MEMENTO_EDITORS)));
participant.closeAllEditors();
participant.restoreState(state);
assertEquals("Expected 2 editors, got: " + Arrays.asList(page.getEditorReferences()), 2,
page.getEditorReferences().length);
assertEquals(new FileEditorInput(fileB), page.getEditorReferences()[0].getEditorInput());
assertEquals(new FileEditorInput(fileA), page.getEditorReferences()[1].getEditorInput());
}
public void testRestoreState_3_7() throws Exception {
createFiles();
XMLMemento memento = XMLMemento.createReadRoot(new InputStreamReader(
CommonTestUtil.getResource(this, "testdata/EditorStateParticipantTest/state-3.7.xml")));
IInteractionContext context = new InteractionContext("id", new InteractionContextScaling());
ContextState state = new ContextState(context, context.getHandleIdentifier(), memento);
participant.restoreState(state);
assertEquals("Expected 2 editors, got: " + Arrays.asList(page.getEditorReferences()), 2,
page.getEditorReferences().length);
assertEquals(new FileEditorInput(fileB), page.getEditorReferences()[0].getEditorInput());
assertEquals(new FileEditorInput(fileA), page.getEditorReferences()[1].getEditorInput());
assertNotNull(memento.getChild(EditorStateParticipant.MEMENTO_EDITORS));
}
public void testRestoreState_4_1() throws Exception {
createFiles();
XMLMemento memento = XMLMemento.createReadRoot(new InputStreamReader(
CommonTestUtil.getResource(this, "testdata/EditorStateParticipantTest/state-4.1.xml")));
IInteractionContext context = new InteractionContext("id", new InteractionContextScaling());
ContextState state = new ContextState(context, context.getHandleIdentifier(), memento);
participant.restoreState(state);
if (participant.is_3_x()) {
// 3.x doesn't have sufficient properties to restore editors persisted with 4.x
assertEquals("Expected 0 editors, got: " + Arrays.asList(page.getEditorReferences()), 0,
page.getEditorReferences().length);
} else {
assertEquals("Expected 2 editors, got: " + Arrays.asList(page.getEditorReferences()), 2,
page.getEditorReferences().length);
assertEquals(new FileEditorInput(fileB), page.getEditorReferences()[0].getEditorInput());
assertEquals(new FileEditorInput(fileA), page.getEditorReferences()[1].getEditorInput());
}
assertNotNull(memento.getChild(EditorStateParticipant.MEMENTO_EDITORS));
}
public void testRestoreStateRetainState() throws Exception {
waitForMylynMonitorToStart();
createFiles();
exceptionOnSave = new RuntimeException("Injected error to cause editor save to fail");
XMLMemento memento = XMLMemento.createReadRoot(
new InputStreamReader(
CommonTestUtil.getResource(this, "testdata/EditorStateParticipantTest/state-3.7.xml")),
"UTF-8");
IInteractionContext context = new InteractionContext("id", new InteractionContextScaling());
ContextState state = new ContextState(context, context.getHandleIdentifier(), memento);
participant.restoreState(state);
XMLMemento memento2 = XMLMemento.createWriteRoot("State");
ContextState state2 = new ContextState(context, context.getHandleIdentifier(), memento2);
participant.saveState(state2, true);
assertEquals(toString(memento), toString(memento2));
}
private void waitForMylynMonitorToStart() {
MonitorUiPlugin.getDefault();
while (Display.getCurrent().readAndDispatch()) {
}
}
public void testNoEditorsState() throws Exception {
createFiles();
PrintStream prevErr = System.err;
try {
IsEmptyOutputStream os = new IsEmptyOutputStream();
System.setErr(new PrintStream(os));
XMLMemento memento = XMLMemento.createReadRoot(new InputStreamReader(
CommonTestUtil.getResource(this, "testdata/EditorStateParticipantTest/state-noEditors.xml")));
IInteractionContext context = new InteractionContext("id", new InteractionContextScaling());
ContextState state = new ContextState(context, context.getHandleIdentifier(), memento);
participant.restoreState(state);
assertTrue(os.isEmpty());
assertEquals(0, page.getEditorReferences().length);
assertNotNull(memento.getChild(EditorStateParticipant.MEMENTO_EDITORS));
} finally {
System.setErr(prevErr);
}
}
private String toString(XMLMemento memento) throws IOException {
File workspace = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile();
OutputStream out = new ByteArrayOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out);
memento.save(writer);
String s = out.toString();
// when reading from disk new lines are escaped
s = s.replaceAll("
", "\r");
s = s.replaceAll("
", "\n");
// always use LF as line separator
s = s.replaceAll("\r\n", "\n");
// resolve workspace variable
s = s.replaceAll("WORKSPACE", workspace.getAbsolutePath());
return s;
}
/**
* Opens an editor for "b.txt" and "a.txt".
*/
private IEditorReference[] createFilesAndOpenEditors() throws Exception {
createFiles();
IEditorInput[] inputs;
if (CommonTestUtil.isEclipse4()) {
// on 3.x openEditors() opens editors starting from the first index
inputs = new IEditorInput[] { new FileEditorInput(fileB), new FileEditorInput(fileA) };
} else {
// on 3.x openEditors() opens editors starting from the last index
inputs = new IEditorInput[] { new FileEditorInput(fileA), new FileEditorInput(fileB) };
}
IEditorDescriptor editor = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor(fileA.getName());
String[] ids = new String[inputs.length];
Arrays.fill(ids, editor.getId());
IEditorReference[] refs = page.openEditors(inputs, ids, IWorkbenchPage.MATCH_NONE);
// realize editors to ensure they are persisted
for (IEditorReference ref : refs) {
ref.getEditor(true);
}
assertEquals(new FileEditorInput(fileB), page.getEditorReferences()[0].getEditorInput());
assertEquals(new FileEditorInput(fileA), page.getEditorReferences()[1].getEditorInput());
return refs;
}
private void createFiles() throws CoreException {
project = ResourcesPlugin.getWorkspace().getRoot().getProject(getClass().getName());
project.create(null);
project.open(null);
fileA = project.getProject().getFile("a.txt");
fileA.create(new ByteArrayInputStream("abc".getBytes()), false, null);
fileB = project.getProject().getFile("b.txt");
fileB.create(new ByteArrayInputStream("abc".getBytes()), false, null);
}
private static class IsEmptyOutputStream extends OutputStream {
private boolean empty = true;
@Override
public void write(int b) throws IOException {
empty = false;
}
public boolean isEmpty() {
return empty;
}
}
}