/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.pyunit.preferences; import java.util.StringTokenizer; import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.core.ILaunchConfiguration; import org.eclipse.jface.preference.BooleanFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceDialog; import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter; import org.eclipse.jface.text.TextPresentation; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.dialogs.PreferencesUtil; import org.python.pydev.core.log.Log; import org.python.pydev.core.tooltips.presenter.AbstractTooltipInformationPresenter; import org.python.pydev.core.tooltips.presenter.ToolTipPresenterHandler; import org.python.pydev.plugin.PydevPlugin; import org.python.pydev.plugin.preferences.PydevPrefs; import org.python.pydev.utils.ComboFieldEditor; import org.python.pydev.utils.LabelFieldEditor; import org.python.pydev.utils.LinkFieldEditor; import org.python.pydev.utils.MultiStringFieldEditor; import com.aptana.shared_core.string.FastStringBuffer; public class PyUnitPrefsPage2 extends FieldEditorPreferencePage implements IWorkbenchPreferencePage { private class PyUnitPageLinkListener implements SelectionListener { private String tag; public PyUnitPageLinkListener(String tag) { this.tag = "--" + tag; } public void widgetSelected(SelectionEvent e) { Text textControl = parametersField.getTextControl(); String currentText = textControl.getText(); StringTokenizer stringTokenizer = new StringTokenizer(currentText); FastStringBuffer buf = new FastStringBuffer(currentText.length() * 2); boolean found = false; while (stringTokenizer.hasMoreTokens()) { String tok = stringTokenizer.nextToken(); if (tok.startsWith(tag)) { found = true; } buf.append(tok); buf.append('\n'); } if (!found) { buf.append(tag); buf.append('='); } else { buf.deleteLast(); //remove the last '\n' } textControl.setText(buf.toString()); textControl.setSelection(textControl.getSize()); textControl.setFocus(); } public void widgetDefaultSelected(SelectionEvent e) { } } public static final int TEST_RUNNER_PYDEV = 0; public static final int TEST_RUNNER_NOSE = 1; public static final int TEST_RUNNER_PY_TEST = 2; public static final String[][] ENTRY_NAMES_AND_VALUES = new String[][] { { "PyDev test runner", Integer.toString(TEST_RUNNER_PYDEV) }, { "Nose test runner", Integer.toString(TEST_RUNNER_NOSE) }, { "Py.test runner", Integer.toString(TEST_RUNNER_PY_TEST) }, }; public static final String TEST_RUNNER = "PYDEV_TEST_RUNNER"; public static final int DEFAULT_TEST_RUNNER = TEST_RUNNER_PYDEV; public static final String TEST_RUNNER_DEFAULT_PARAMETERS = "PYDEV_TEST_RUNNER_DEFAULT_PARAMETERS"; public static final String DEFAULT_TEST_RUNNER_DEFAULT_PARAMETERS = "--verbosity 0"; public static final String USE_PYUNIT_VIEW = "PYDEV_USE_PYUNIT_VIEW"; public static final boolean DEFAULT_USE_PYUNIT_VIEW = true; public static final String LAUNCH_CONFIG_OVERRIDE_PYUNIT_RUN_PARAMS_CHOICE = "LAUNCH_CONFIG_OVERRIDE_PYUNIT_RUN_PARAMS_CHOICE"; public static final String LAUNCH_CONFIG_OVERRIDE_TEST_RUNNER = "LAUNCH_CONFIG_OVERRIDE_TEST_RUNNER"; public static final String LAUNCH_CONFIG_OVERRIDE_PYUNIT_RUN_PARAMS = "LAUNCH_CONFIG_OVERRIDE_PYUNIT_RUN_PARAMS"; private MultiStringFieldEditor parametersField; private ToolTipPresenterHandler tooltipPresenter; /** * Create the preference page. */ public PyUnitPrefsPage2() { super(FLAT); setPreferenceStore(PydevPlugin.getDefault().getPreferenceStore()); } /** * Creates the editors */ protected void createFieldEditors() { IInformationPresenter presenter = new AbstractTooltipInformationPresenter() { @Override protected void onUpdatePresentation(String hoverInfo, TextPresentation presentation) { } @Override protected void onHandleClick(Object data) { } }; Composite p = getFieldEditorParent(); tooltipPresenter = new ToolTipPresenterHandler(p.getShell(), presenter, "Tip: Click on the link to add it as a parameter to the test runner."); addField(createTestRunnerEditor(p)); parametersField = new MultiStringFieldEditor(TEST_RUNNER_DEFAULT_PARAMETERS, "Parameters for test runner (click links below to add flags)", p); addField(parametersField); addField(new BooleanFieldEditor(USE_PYUNIT_VIEW, "Show the results in the unittest results view?", p)); String s = "Note: if unchecked, no xml-rpc communication will be done when running tests\nand the output will only be shown in the console."; addField(new LabelFieldEditor("LabelFieldEditor", s, p)); String s2 = "Parameters for PyDev test runner (hover for description):" + ""; addField(new LabelFieldEditor("LabelFieldEditor2", s2, p)); add("--<a>verbosity</a>=number", "verbosity", "Sets the verbosity level for the run (0-9)\n" + " 0: almost no output\n" + " 9: many details", p); add("--<a>jobs</a>=number", "jobs", "The number of processes to be used to run the tests.\n\n" + "The --split_jobs flag actually mandates how the tests will be scheduled (if jobs > 1).", p); add("--<a>split_jobs</a>=tests|module", "split_jobs", "tests: if 'tests' is passed (default), a process will randomly get a\n" + "\tnew test to be run after the current one finishes running.\n\n" + "module: if 'module' is passed, a given job will always run all the\n" + "\ttests from a module and then get a new module to run tests from.", p); add("--<a>include_files</a>=comma separated list of patterns to match files to include", "include_files", "Patters to match filenames to be included during test discovery.\n\n" + "Patters are fnmatch-style patterns (i.e.: test*, todo* and not regexps).\n\n" + "Note that *.py,*.pyw files are already pre-selected, so, patterns\n" + "will be matched against those pre-selected by default.", p); add("--<a>exclude_files</a>=comma separated list of patterns to match files to exclude", "exclude_files", "Patters to match filenames to be excluded during test discovery.\n\n" + "Patters are fnmatch-style patterns (i.e.: test*, todo* and not regexps).\n\n" + "Note that *.py,*.pyw files are already pre-selected, so, patterns\n" + "will be matched against those pre-selected by default.", p); add("--<a>include_tests</a>=comma separated list of patterns to match tests to include", "include_tests", "Patters to match tests (method names) to be included during test discovery.\n\n" + "Patters are fnmatch-style patterns (i.e.: *_todo, *_slow and not regexps).\n\n", p); add("--<a>exclude_tests</a>=comma separated list of patterns to match tests to exclude", "exclude_tests", "Patters to match tests (method names) to be excluded during test discovery.\n\n" + "Patters are fnmatch-style patterns (i.e.: *_todo, *_slow and not regexps).\n\n", p); } private void add(String linkText, String flag, String tooltip, Composite p) { addField(new LinkFieldEditor("link_" + flag, linkText, p, new PyUnitPrefsPage2.PyUnitPageLinkListener(flag), tooltip + "\n", tooltipPresenter)); } public static ComboFieldEditor createTestRunnerEditor(Composite p) { return new ComboFieldEditor(TEST_RUNNER, "Test Runner", ENTRY_NAMES_AND_VALUES, p); } /** * Initialize the preference page. */ public void init(IWorkbench workbench) { // Initialize the preference page } public static String getTestRunnerParameters(ILaunchConfiguration config) { boolean override = false; try { override = config.getAttribute(LAUNCH_CONFIG_OVERRIDE_PYUNIT_RUN_PARAMS_CHOICE, false); } catch (CoreException e) { Log.log(e); } IPreferenceStore prefs = PydevPrefs.getPreferenceStore(); int testRunner = prefs.getInt(TEST_RUNNER); String ret = prefs.getString(TEST_RUNNER_DEFAULT_PARAMETERS); if (override) { try { testRunner = config.getAttribute(LAUNCH_CONFIG_OVERRIDE_TEST_RUNNER, testRunner); } catch (CoreException e) { Log.log(e); } try { ret = config.getAttribute(LAUNCH_CONFIG_OVERRIDE_PYUNIT_RUN_PARAMS, ret); } catch (CoreException e) { Log.log(e); } } switch (testRunner) { case TEST_RUNNER_NOSE: ret = "--nose-params " + ret; //From this point onwards, only nose parameters. break; case TEST_RUNNER_PY_TEST: ret = "--py-test-params " + ret; //From this point onwards, only py.test parameters. break; } return ret; } public static boolean getUsePyUnitView() { return PydevPrefs.getPreferenceStore().getBoolean(USE_PYUNIT_VIEW); } public static void showPage() { String id = "org.python.pydev.prefs.pyunitPage"; PreferenceDialog prefDialog = PreferencesUtil.createPreferenceDialogOn(null, id, null, null); prefDialog.open(); } }