net.sf.webcat.eclipse.cxxtest.ui.TestRunnerViewPart.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.webcat.eclipse.cxxtest.ui.TestRunnerViewPart.java

Source

/*==========================================================================*\
 |  $Id$
 |*-------------------------------------------------------------------------*|
 |  Copyright (C) 2006-2009 Virginia Tech 
 |
 |   This file is part of Web-CAT Eclipse Plugins.
 |
 |   Web-CAT is free software; you can redistribute it and/or modify
 |   it under the terms of the GNU General Public License as published by
 |   the Free Software Foundation; either version 2 of the License, or
 |   (at your option) any later version.
 |
 |   Web-CAT 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
 |   GNU General Public License for more details.
 |
 |   You should have received a copy of the GNU General Public License
 |   along with Web-CAT; if not, see <http://www.gnu.org/licenses/>.
\*==========================================================================*/

package net.sf.webcat.eclipse.cxxtest.ui;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.Vector;

import net.sf.webcat.eclipse.cxxtest.CxxTestPlugin;
import net.sf.webcat.eclipse.cxxtest.i18n.Messages;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestAssertion;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestBase;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestMethod;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestStackFrame;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestSuite;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestSuiteChild;
import net.sf.webcat.eclipse.cxxtest.model.ICxxTestSuiteError;
import net.sf.webcat.eclipse.cxxtest.model.IDerefereeSummary;
import net.sf.webcat.eclipse.cxxtest.model.IDerefereeLeak;

import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.custom.ViewForm;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.part.ViewPart;

/**
 * The view part that represents the CxxTest view in the Eclipse IDE. This
 * view displays the results of the CxxTest execution and flags any tests
 * that failed.
 * 
 * Influenced greatly by the same JUnit class.
 * 
 * @author  Tony Allevato (Virginia Tech Computer Science)
 * @author  latest changes by: $Author$
 * @version $Revision$ $Date$
 */
public class TestRunnerViewPart extends ViewPart {
    private class DetailsContentProvider implements ITreeContentProvider {
        public Object[] getElements(Object inputElement) {
            if (inputElement == null) {
                return new Object[0];
            } else if (inputElement instanceof IDerefereeSummary) {
                IDerefereeSummary info = (IDerefereeSummary) inputElement;
                String[] array = new String[7];

                array[0] = MessageFormat.format(Messages.TestRunnerViewPart_TotalBytesAllocated,
                        info.getTotalBytesAllocated());
                array[1] = MessageFormat.format(Messages.TestRunnerViewPart_MaximumBytesInUse,
                        info.getMaxBytesInUse());
                array[2] = MessageFormat.format(Messages.TestRunnerViewPart_CallsToNew, info.getCallsToNew());
                array[3] = MessageFormat.format(Messages.TestRunnerViewPart_CallsToDeleteNonNull,
                        info.getCallsToDelete());
                array[4] = MessageFormat.format(Messages.TestRunnerViewPart_CallsToArrayNew,
                        info.getCallsToArrayNew());
                array[5] = MessageFormat.format(Messages.TestRunnerViewPart_CallsToArrayDeleteNonNull,
                        info.getCallsToArrayDelete());
                array[6] = MessageFormat.format(Messages.TestRunnerViewPart_CallsToDeleteNull,
                        info.getCallsToDeleteNull());
                return array;
            } else {
                return (Object[]) inputElement;
            }
        }

        public void dispose() {
        }

        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }

        public Object[] getChildren(Object parentElement) {
            if (parentElement instanceof ICxxTestAssertion) {
                ICxxTestAssertion cta = (ICxxTestAssertion) parentElement;
                return cta.getStackTrace();
            } else if (parentElement instanceof ICxxTestSuiteError) {
                ICxxTestSuiteError cta = (ICxxTestSuiteError) parentElement;
                return cta.getStackTrace();
            } else if (parentElement instanceof IDerefereeLeak) {
                IDerefereeLeak mwl = (IDerefereeLeak) parentElement;
                return mwl.getStackTrace();
            } else {
                return null;
            }
        }

        public Object getParent(Object element) {
            return null;
        }

        public boolean hasChildren(Object element) {
            if (element instanceof ICxxTestAssertion) {
                ICxxTestAssertion cta = (ICxxTestAssertion) element;
                return cta.getStackTrace() != null;
            } else if (element instanceof ICxxTestSuiteError) {
                ICxxTestSuiteError cta = (ICxxTestSuiteError) element;
                return cta.getStackTrace() != null;
            } else if (element instanceof IDerefereeLeak) {
                IDerefereeLeak leak = (IDerefereeLeak) element;
                return leak.getStackTrace() != null;
            } else
                return false;
        }
    }

    private class DetailsLabelProvider extends LabelProvider {
        public String getText(Object element) {
            if (element instanceof ICxxTestAssertion) {
                ICxxTestAssertion assertion = (ICxxTestAssertion) element;
                return assertion.getMessage(true);
            } else if (element instanceof ICxxTestSuiteError) {
                ICxxTestSuiteError assertion = (ICxxTestSuiteError) element;
                return assertion.getMessage();
            } else if (element instanceof IDerefereeLeak) {
                IDerefereeLeak leak = (IDerefereeLeak) element;

                if (leak.getStackTrace() != null && leak.getStackTrace().length > 0) {
                    return leak.toString() + Messages.TestRunnerViewPart_AllocatedUsingSuffix;
                } else {
                    return leak.toString();
                }
            } else if (element instanceof ICxxTestStackFrame) {
                ICxxTestStackFrame ste = (ICxxTestStackFrame) element;
                return ste.toString();
            } else {
                return element.toString();
            }
        }

        public Image getImage(Object element) {
            if (element instanceof ICxxTestAssertion || element instanceof ICxxTestSuiteError) {
                ICxxTestBase test = (ICxxTestBase) element;

                switch (test.getStatus()) {
                case ICxxTestBase.STATUS_OK:
                    return assertTraceIcon;

                case ICxxTestBase.STATUS_WARNING:
                    return assertWarnIcon;

                case ICxxTestBase.STATUS_FAILED:
                    return assertFailureIcon;

                case ICxxTestBase.STATUS_ERROR:
                    return assertErrorIcon;

                default:
                    return null;
                }
            } else if (element instanceof ICxxTestStackFrame || element instanceof IDerefereeLeak) {
                return stackFrameIcon;
            } else
                return null;
        }
    }

    private final Image testOkIcon = TestRunnerViewPart.createImage("obj16/testok.gif"); //$NON-NLS-1$
    private final Image testWarnIcon = TestRunnerViewPart.createImage("obj16/testwarn.gif"); //$NON-NLS-1$
    private final Image testFailureIcon = TestRunnerViewPart.createImage("obj16/testfail.gif"); //$NON-NLS-1$
    private final Image testErrorIcon = TestRunnerViewPart.createImage("obj16/testerr.gif"); //$NON-NLS-1$
    private final Image assertTraceIcon = TestRunnerViewPart.createImage("obj16/asserttrace.gif"); //$NON-NLS-1$
    private final Image assertWarnIcon = TestRunnerViewPart.createImage("obj16/assertwarn.gif"); //$NON-NLS-1$
    private final Image assertFailureIcon = TestRunnerViewPart.createImage("obj16/assertfail.gif"); //$NON-NLS-1$
    private final Image assertErrorIcon = TestRunnerViewPart.createImage("obj16/asserterror.gif"); //$NON-NLS-1$
    private final Image stackFrameIcon = TestRunnerViewPart.createImage("obj16/stkfrm_obj.gif"); //$NON-NLS-1$

    public static final String ID = CxxTestPlugin.PLUGIN_ID + ".TestRunnerView"; //$NON-NLS-1$

    private Composite parent;

    private Composite counterComposite;

    private CounterPanel counterPanel;

    private CxxTestProgressBar progressBar;

    private CTabFolder tabFolder;

    private SashForm sashForm;

    private TreeViewer detailViewer;

    private int orientation = VIEW_ORIENTATION_AUTOMATIC;

    private int currentOrientation;

    private ILaunch currentLaunch;

    private ICProject launchedProject;

    protected Vector<TestRunTab> testRunTabs = new Vector<TestRunTab>();

    private TestRunTab activeRunTab;

    private Clipboard clipboard;

    private StopAction stopAction;
    private ToggleOrientationAction[] toggleOrientationActions;

    private static final int VIEW_ORIENTATION_VERTICAL = 0;
    private static final int VIEW_ORIENTATION_HORIZONTAL = 1;
    private static final int VIEW_ORIENTATION_AUTOMATIC = 2;

    private class StopAction extends Action {
        public StopAction() {
            setText(Messages.TestRunnerViewPart_TerminateLabel);
            setToolTipText(Messages.TestRunnerViewPart_TerminateTooltip);

            setDisabledImageDescriptor(CxxTestPlugin.getImageDescriptor("dlcl16/stop.gif")); //$NON-NLS-1$
            setHoverImageDescriptor(CxxTestPlugin.getImageDescriptor("elcl16/stop.gif")); //$NON-NLS-1$
            setImageDescriptor(CxxTestPlugin.getImageDescriptor("elcl16/stop.gif")); //$NON-NLS-1$
        }

        public void run() {
            stopTest();
        }
    }

    private class ToggleOrientationAction extends Action {
        private final int actionOrientation;

        public ToggleOrientationAction(int orientation) {
            super("", AS_RADIO_BUTTON); //$NON-NLS-1$

            if (orientation == TestRunnerViewPart.VIEW_ORIENTATION_HORIZONTAL) {
                setText(Messages.TestRunnerViewPart_HorizontalViewLabel);
                setImageDescriptor(CxxTestPlugin.getImageDescriptor("elcl16/th_horizontal.gif")); //$NON-NLS-1$
            } else if (orientation == TestRunnerViewPart.VIEW_ORIENTATION_VERTICAL) {
                setText(Messages.TestRunnerViewPart_VerticalViewLabel);
                setImageDescriptor(CxxTestPlugin.getImageDescriptor("elcl16/th_vertical.gif")); //$NON-NLS-1$
            } else if (orientation == TestRunnerViewPart.VIEW_ORIENTATION_AUTOMATIC) {
                setText(Messages.TestRunnerViewPart_AutomaticViewLabel);
                setImageDescriptor(CxxTestPlugin.getImageDescriptor("elcl16/th_automatic.gif")); //$NON-NLS-1$
            }

            actionOrientation = orientation;
        }

        public int getOrientation() {
            return actionOrientation;
        }

        public void run() {
            if (isChecked()) {
                orientation = actionOrientation;
                computeOrientation();
            }
        }
    }

    public void createPartControl(Composite parent) {
        this.parent = parent;
        parent.addControlListener(new ControlAdapter() {
            public void controlResized(ControlEvent e) {
                computeOrientation();
            }
        });

        setContentDescription(""); //$NON-NLS-1$

        clipboard = new Clipboard(Display.getCurrent());

        GridLayout layout = new GridLayout();
        layout.marginWidth = 0;
        layout.marginHeight = 0;
        parent.setLayout(layout);

        configureToolBar();

        counterComposite = createProgressCountPanel(parent);
        counterComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));

        SashForm sashForm = createSashForm(parent);
        sashForm.setLayoutData(new GridData(GridData.FILL_BOTH));
    }

    private SashForm createSashForm(Composite parent) {
        sashForm = new SashForm(parent, SWT.HORIZONTAL);
        ViewForm top = new ViewForm(sashForm, SWT.NONE);
        tabFolder = createTestRunTabs(top);
        top.setContent(tabFolder);

        ViewForm bottom = new ViewForm(sashForm, SWT.NONE);
        CLabel label = new CLabel(bottom, SWT.NONE);
        label.setText(Messages.TestRunnerViewPart_DetailsLabel);
        bottom.setTopLeft(label);

        detailViewer = new TreeViewer(bottom, SWT.NONE);
        detailViewer.setContentProvider(new DetailsContentProvider());
        detailViewer.setLabelProvider(new DetailsLabelProvider());
        detailViewer.addSelectionChangedListener(new ISelectionChangedListener() {
            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection selection = (IStructuredSelection) detailViewer.getSelection();

                if (selection.size() > 0)
                    showTest(selection.getFirstElement());
            }
        });
        bottom.setContent(detailViewer.getTree());

        sashForm.setWeights(new int[] { 50, 50 });
        return sashForm;
    }

    private Composite createProgressCountPanel(Composite parent) {
        Composite composite = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        composite.setLayout(layout);
        setCounterColumns(layout);

        counterPanel = new CounterPanel(composite);
        counterPanel.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));
        progressBar = new CxxTestProgressBar(composite);
        progressBar.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.HORIZONTAL_ALIGN_FILL));

        return composite;
    }

    private void configureToolBar() {
        IActionBars actionBars = getViewSite().getActionBars();
        IToolBarManager toolBar = actionBars.getToolBarManager();
        IMenuManager viewMenu = actionBars.getMenuManager();

        toggleOrientationActions = new ToggleOrientationAction[] {
                new ToggleOrientationAction(VIEW_ORIENTATION_VERTICAL),
                new ToggleOrientationAction(VIEW_ORIENTATION_HORIZONTAL),
                new ToggleOrientationAction(VIEW_ORIENTATION_AUTOMATIC) };

        stopAction = new StopAction();
        stopAction.setEnabled(false);

        toolBar.add(stopAction);

        for (int i = 0; i < toggleOrientationActions.length; ++i)
            viewMenu.add(toggleOrientationActions[i]);

        viewMenu.add(new Separator());
        actionBars.updateActionBars();
    }

    public void dispose() {
        disposeIcons();
    }

    private void disposeIcons() {
        testOkIcon.dispose();
        testWarnIcon.dispose();
        testFailureIcon.dispose();
        testErrorIcon.dispose();
        assertTraceIcon.dispose();
        assertWarnIcon.dispose();
        assertFailureIcon.dispose();
        assertErrorIcon.dispose();
    }

    private CTabFolder createTestRunTabs(Composite parent) {
        CTabFolder tabFolder = new CTabFolder(parent, SWT.TOP);
        tabFolder.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL));

        TestHierarchyTab hierarchyTab = new TestHierarchyTab();
        hierarchyTab.createTabControl(tabFolder, clipboard, this);
        testRunTabs.addElement(hierarchyTab);

        TestMemoryTab memoryTab = new TestMemoryTab();
        memoryTab.createTabControl(tabFolder, clipboard, this);
        testRunTabs.addElement(memoryTab);

        if (tabFolder.getItemCount() > 0) {
            tabFolder.setSelection(0);
            activeRunTab = testRunTabs.firstElement();
        }

        tabFolder.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent event) {
                testTabChanged(event);
            }
        });

        return tabFolder;
    }

    private void testTabChanged(SelectionEvent event) {
        for (Enumeration<TestRunTab> e = testRunTabs.elements(); e.hasMoreElements();) {
            TestRunTab v = e.nextElement();
            if (((CTabFolder) event.widget).getSelection().getText() == v.getName()) {
                //            v.setSelectedTest(activeRunTab.getSelectedTestObject());
                activeRunTab = v;
                activeRunTab.activate();
            }
        }
    }

    private void computeOrientation() {
        if (orientation != VIEW_ORIENTATION_AUTOMATIC) {
            currentOrientation = orientation;
            setOrientation(currentOrientation);
        } else {
            Point size = parent.getSize();
            if (size.x != 0 && size.y != 0) {
                if (size.x > size.y)
                    setOrientation(VIEW_ORIENTATION_HORIZONTAL);
                else
                    setOrientation(VIEW_ORIENTATION_VERTICAL);
            }
        }
    }

    private void setOrientation(int orientation) {
        if ((sashForm == null) || sashForm.isDisposed())
            return;

        boolean horizontal = orientation == VIEW_ORIENTATION_HORIZONTAL;
        sashForm.setOrientation(horizontal ? SWT.HORIZONTAL : SWT.VERTICAL);

        for (int i = 0; i < toggleOrientationActions.length; ++i)
            toggleOrientationActions[i].setChecked(orientation == toggleOrientationActions[i].getOrientation());

        currentOrientation = orientation;
        GridLayout layout = (GridLayout) counterComposite.getLayout();
        setCounterColumns(layout);
        parent.layout();
    }

    private void setCounterColumns(GridLayout layout) {
        if (currentOrientation == VIEW_ORIENTATION_HORIZONTAL)
            layout.numColumns = 2;
        else
            layout.numColumns = 1;
    }

    public void setFocus() {
    }

    public void showTest(Object test) {
        new OpenTestAction(this, test).run();
    }

    public void stopTest() {
        if (currentLaunch != null) {
            try {
                currentLaunch.terminate();
            } catch (DebugException e) {
            }

            currentLaunch = null;
        }

        setContentDescription(""); //$NON-NLS-1$
        stopAction.setEnabled(false);
    }

    public void handleObjectSelected(Object obj) {
        showDetails(obj);
    }

    private void showDetails(Object obj) {
        if (obj == null)
            detailViewer.setInput(null);
        else {
            if (obj instanceof ICxxTestMethod) {
                ICxxTestMethod test = (ICxxTestMethod) obj;
                ICxxTestAssertion[] assertions = test.getFailedAssertions();
                detailViewer.setInput(assertions);
            } else if (obj instanceof ICxxTestSuiteError) {
                ICxxTestSuiteError test = (ICxxTestSuiteError) obj;
                detailViewer.setInput(new Object[] { test });
            } else if (obj instanceof IDerefereeLeak) {
                IDerefereeLeak leak = (IDerefereeLeak) obj;
                detailViewer.setInput(new Object[] { leak });
            } else if (obj instanceof IDerefereeSummary) {
                detailViewer.setInput(obj);
            }

            detailViewer.expandAll();
        }
    }

    public static Image createImage(String path) {
        try {
            URL base = Platform.getBundle(CxxTestPlugin.PLUGIN_ID).getEntry("/icons/full/"); //$NON-NLS-1$
            URL url = new URL(base, path);

            ImageDescriptor id = ImageDescriptor.createFromURL(url);
            return id.createImage();
        } catch (MalformedURLException e) {
        }

        return null;
    }

    public void testRunStarted(ICProject project, ILaunch launch) {
        launchedProject = project;

        for (Enumeration<TestRunTab> e = testRunTabs.elements(); e.hasMoreElements();) {
            TestRunTab v = e.nextElement();
            v.testRunStarted(project, launch);
        }

        counterPanel.reset();
        progressBar.reset();

        currentLaunch = launch;

        String name = ""; //$NON-NLS-1$
        try {
            name = launch.getLaunchConfiguration().getAttribute(ICDTLaunchConfigurationConstants.ATTR_PROJECT_NAME,
                    ""); //$NON-NLS-1$
        } catch (CoreException e) {
        }

        detailViewer.setInput(null);
        setContentDescription(MessageFormat.format(Messages.TestRunnerViewPart_RunningMessage, name));

        stopAction.setEnabled(true);
    }

    public ICProject getLaunchedProject() {
        return launchedProject;
    }

    public void testRunEnded() {
        currentLaunch = null;
        stopTest();

        for (Enumeration<TestRunTab> e = testRunTabs.elements(); e.hasMoreElements();) {
            TestRunTab v = e.nextElement();
            v.testRunEnded();
        }
    }

    public void setSummary(ICxxTestSuite[] suites) {
        if (suites == null)
            return;

        if (suites.length > 0)
            getViewSite().getPage().activate(this);

        int totalTests = 0, failedTests = 0, errorTests = 0;

        for (int i = 0; i < suites.length; i++) {
            ICxxTestSuiteChild[] tests = suites[i].getChildren(true);
            totalTests += tests.length;

            for (int j = 0; j < tests.length; j++) {
                if (tests[j].getStatus() == ICxxTestBase.STATUS_ERROR)
                    errorTests++;
                else if (tests[j].getStatus() == ICxxTestBase.STATUS_FAILED)
                    failedTests++;
            }
        }

        counterPanel.reset();
        counterPanel.setRunValue(totalTests);
        counterPanel.setFailureValue(failedTests);
        counterPanel.setErrorValue(errorTests);

        progressBar.reset();
        progressBar.setMaximum(totalTests);
        progressBar.step(failedTests + errorTests);
        progressBar.refresh(failedTests + errorTests > 0);
    }
}