/* Copyright (C) 2009 Mobile Sorcery AB
This program is free software; you can redistribute it and/or modify it
under the terms of the Eclipse Public License v1.0.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the Eclipse Public License v1.0 for
more details.
You should have received a copy of the Eclipse Public License v1.0 along
with this program. It is also available at http://www.eclipse.org/legal/epl-v10.html
*/
package com.mobilesorcery.sdk.testing.internal.ui;
import java.util.Random;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.ITextEditor;
import com.mobilesorcery.sdk.testing.IRelaunchableTestSession;
import com.mobilesorcery.sdk.testing.ITest;
import com.mobilesorcery.sdk.testing.ITestSession;
import com.mobilesorcery.sdk.testing.ITestSessionListener;
import com.mobilesorcery.sdk.testing.Test;
import com.mobilesorcery.sdk.testing.TestManager;
import com.mobilesorcery.sdk.testing.TestResult;
import com.mobilesorcery.sdk.testing.TestSessionEvent;
import com.mobilesorcery.sdk.testing.emulator.EmulatorTestSession;
public class UnittestView extends ViewPart implements ITestSessionListener {
class RerunAction extends Action {
public RerunAction() {
setText("Run Again");
setToolTipText("Run Again");
}
public void run() {
ITestSession session = testRun.getTestSession();
if (session instanceof IRelaunchableTestSession) {
ILaunchConfiguration launchConfiguration = ((IRelaunchableTestSession) session).getLaunchConfiguration();
DebugUITools.launch(launchConfiguration, "run");
}
}
}
class GotoLineAction extends Action {
private ISelection selection;
public GotoLineAction() {
setText("Goto");
}
public void setSelection(ISelection selection) {
this.selection = selection;
this.setEnabled(computeEnabled());
}
private boolean computeEnabled() {
return run(true);
}
public void run() {
run(false);
}
public boolean run(boolean noAction) {
if (selection instanceof IStructuredSelection) {
IStructuredSelection sSelection = (IStructuredSelection) selection;
Object o = sSelection.getFirstElement();
if (o instanceof ITest) {
ITest test = (ITest) o;
TestResult result = testRun.getTestSession().getTestResult();
Object fileObj = result.getProperty(test, EmulatorTestSession.FILE_KEY);
Object lineObj = result.getProperty(test, EmulatorTestSession.LINE_KEY);
if (fileObj != null) {
IWorkspace ws = ResourcesPlugin.getWorkspace();
IFile[] files = ws.getRoot().findFilesForLocation(new Path(fileObj.toString()));
boolean hasFileInWorkspace = files.length > 0;
if (hasFileInWorkspace && !noAction) {
try {
IEditorPart part = IDE.openEditor(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(), files[0]);
if (part instanceof ITextEditor) {
ITextEditor textEditor = (ITextEditor) part;
IDocumentProvider provider= textEditor.getDocumentProvider();
IDocument document= provider.getDocument(textEditor.getEditorInput());
int start = document.getLineOffset(Integer.parseInt(lineObj.toString()) - 1);
textEditor.selectAndReveal(start, 0);
}
} catch (PartInitException e) {
throw new RuntimeException(e);
} catch (NumberFormatException e) {
// Ignore, just don't show.
} catch (org.eclipse.jface.text.BadLocationException e) {
// Ignore, just don't show.
}
}
return hasFileInWorkspace;
}
}
}
return false;
}
}
class ExpandAllAction extends Action {
public ExpandAllAction() {
setText("E&xpand All");
setToolTipText("Expand All");
}
public void run() {
testRun.expandAll();
}
}
class DummyTest extends Test {
private boolean fail;
public DummyTest(String name, boolean fail) {
super(name);
this.fail = fail;
}
public void run(TestResult result) throws Exception {
Thread.sleep(new Random(System.currentTimeMillis()).nextInt(2000));
if (fail) {
throw new IllegalArgumentException();
}
}
}
private TestRunComposite testRun;
private GotoLineAction gotoLineAction;
public final static String ID = "com.mobilesorcery.sdk.testing.view";
public void createPartControl(Composite parent) {
testRun = new TestRunComposite(parent, SWT.NONE);
MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
handleMenuAboutToShow(manager);
}
});
getSite().registerContextMenu(menuMgr, testRun.getSelectionProvider());
Menu menu = menuMgr.createContextMenu(testRun);
// TODO: Fixme.
testRun.setMenu(menu);
TreeViewer viewer = testRun.getTreeViewer();
gotoLineAction = new GotoLineAction();
viewer.getControl().setMenu(menu);
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
gotoLineAction.setSelection(event.getSelection());
gotoLineAction.run();
}
});
TestManager.getInstance().addSessionListener(this);
testRun.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
TestManager.getInstance().removeSessionListener(
UnittestView.this);
}
});
testRun.setCurrentTestSession(TestManager.getInstance().getLastSession());
}
public void setFocus() {
// TODO Auto-generated method stub
}
void handleMenuAboutToShow(IMenuManager manager) {
IStructuredSelection selection = (IStructuredSelection) testRun
.getSelectionProvider().getSelection();
ITestSession session = testRun.getTestSession();
if (session instanceof IRelaunchableTestSession) {
manager.add(new RerunAction());
manager.add(new Separator());
}
if (!selection.isEmpty()) {
ITest testElement = (ITest) selection.getFirstElement();
gotoLineAction.setSelection(selection);
manager.add(gotoLineAction);
if (session.getTestCount() > 0) {
manager.add(new ExpandAllAction());
}
}
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS
+ "-end")); //$NON-NLS-1$
}
public void handleEvent(final TestSessionEvent event) {
if (event.type == TestSessionEvent.SESSION_STARTED) {
getSite().getWorkbenchWindow().getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
getSite().getPage().activate(getSite().getPart());
testRun.setCurrentTestSession(event.session);
}
});
}
}
}