/******************************************************************************* * Copyright (c) 2009, 2010 Sven Kiera * 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 *******************************************************************************/ package org.phpsrc.eclipse.pti.tools.phpunit.ui.preferences; import java.io.File; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.window.Window; import org.eclipse.php.internal.ui.preferences.IStatusChangeListener; import org.eclipse.php.internal.ui.preferences.util.Key; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.dialogs.ResourceSelectionDialog; import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer; import org.phpsrc.eclipse.pti.core.search.PHPSearchMatch; import org.phpsrc.eclipse.pti.core.search.ui.dialogs.FilteredPHPClassSelectionDialog; import org.phpsrc.eclipse.pti.library.pear.ui.preferences.AbstractPEARPHPToolConfigurationBlock; import org.phpsrc.eclipse.pti.tools.phpunit.IPHPUnitConstants; import org.phpsrc.eclipse.pti.tools.phpunit.PHPUnitPlugin; import org.phpsrc.eclipse.pti.tools.phpunit.core.PHPUnit; @SuppressWarnings("restriction") public class PHPUnitConfigurationBlock extends AbstractPEARPHPToolConfigurationBlock { private static final Key PREF_PHP_EXECUTABLE = getPHPUnitKey(PHPUnitPreferenceNames.PREF_PHP_EXECUTABLE); private static final Key PREF_PEAR_LIBRARY = getPHPUnitKey(PHPUnitPreferenceNames.PREF_PEAR_LIBRARY); private static final Key PREF_DEBUG_PRINT_OUTPUT = getPHPUnitKey(PHPUnitPreferenceNames.PREF_DEBUG_PRINT_OUTPUT); private static final Key PREF_BOOSTRAP = getPHPUnitKey(PHPUnitPreferenceNames.PREF_BOOTSTRAP); private static final Key PREF_TEST_FILE_PATTERN_FOLDER = getPHPUnitKey(PHPUnitPreferenceNames.PREF_TEST_FILE_PATTERN_FOLDER); private static final Key PREF_SOURCE_FILE_PATTERN_FOLDER = getPHPUnitKey(PHPUnitPreferenceNames.PREF_SOURCE_FILE_PATTERN_FOLDER); private static final Key PREF_TEST_FILE_PATTERN_FILE = getPHPUnitKey(PHPUnitPreferenceNames.PREF_TEST_FILE_PATTERN_FILE); private static final Key PREF_TEST_FILE_SUPER_CLASS = getPHPUnitKey(PHPUnitPreferenceNames.PREF_TEST_FILE_SUPER_CLASS); private static final Key PREF_GENERATE_CODE_COVERAGE = getPHPUnitKey(PHPUnitPreferenceNames.PREF_GENERATE_CODE_COVERAGE); private static final Key PREF_NO_NAMESPACE_CHECK = getPHPUnitKey(PHPUnitPreferenceNames.PREF_NO_NAMESPACE_CHECK); public static final String TEST_FILE_PATTERN_FOLDER_DEFAULT = File.separatorChar + IPHPUnitConstants.TEST_FILE_PATTERN_PLACEHOLDER_PROJECT + File.separatorChar + "tests" + File.separatorChar + IPHPUnitConstants.TEST_FILE_PATTERN_PLACEHOLDER_DIR; public static final String TEST_FILE_PATTERN_FILE_DEFAULT = IPHPUnitConstants.TEST_FILE_PATTERN_PLACEHOLDER_FILENAME + "Test." + IPHPUnitConstants.TEST_FILE_PATTERN_PLACEHOLDER_FILE_EXTENSION; protected Text fBootstrap; protected Button fFileButton; protected Text fTestFilePatternFolder; protected Text fSourceFilePatternFolder; protected Text fTestFilePatternFile; protected Text fTestFileSuperClass; protected Button fGenerateCodeCoverageCheckbox; protected Button fNoNamespaceCheckCheckbox; public PHPUnitConfigurationBlock(IStatusChangeListener context, IProject project, IWorkbenchPreferenceContainer container) { super(context, project, getKeys(), container); } private static Key[] getKeys() { return new Key[] { PREF_PHP_EXECUTABLE, PREF_PEAR_LIBRARY, PREF_DEBUG_PRINT_OUTPUT, PREF_BOOSTRAP, PREF_TEST_FILE_PATTERN_FOLDER, PREF_TEST_FILE_PATTERN_FILE, PREF_TEST_FILE_SUPER_CLASS, PREF_GENERATE_CODE_COVERAGE, PREF_NO_NAMESPACE_CHECK, PREF_SOURCE_FILE_PATTERN_FOLDER }; } protected Composite createToolContents(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(); layout.numColumns = 1; layout.verticalSpacing = 10; layout.marginWidth = 0; layout.horizontalSpacing = 0; composite.setLayout(layout); Group patternGroup = createTestFilePatternGroup(composite); patternGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Group optionGroup = createPHPOptionsGroup(composite); optionGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); unpackTestFilePattern(); unpackBootstrap(); validateSettings(null, null, null); return composite; } private Group createTestFilePatternGroup(Composite folder) { final Group testFilePatternGroup = new Group(folder, SWT.RESIZE); testFilePatternGroup.setText("Test Case"); final GridLayout testFilePatternLayout = new GridLayout(); testFilePatternLayout.numColumns = 3; testFilePatternLayout.verticalSpacing = 9; testFilePatternGroup.setLayout(testFilePatternLayout); Label testFileSuperClassLabel = new Label(testFilePatternGroup, SWT.NULL); testFileSuperClassLabel.setText("SuperClass:"); fTestFileSuperClass = new Text(testFilePatternGroup, SWT.BORDER | SWT.SINGLE); fTestFileSuperClass .setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); Button fTestFileSuperClassButton = new Button(testFilePatternGroup, SWT.PUSH); fTestFileSuperClassButton.setText("Search..."); fTestFileSuperClassButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { FilteredPHPClassSelectionDialog dialog = new FilteredPHPClassSelectionDialog( getShell(), false); if (dialog.open() == Window.OK) { PHPSearchMatch result = (PHPSearchMatch) dialog .getFirstResult(); if (result != null && result.getElement() != null) fTestFileSuperClass.setText(result.getElement() .getElementName()); } } }); Label testFilePatternFolderLabel = new Label(testFilePatternGroup, SWT.NULL); testFilePatternFolderLabel.setText("Test Folder Pattern:"); fTestFilePatternFolder = new Text(testFilePatternGroup, SWT.BORDER | SWT.SINGLE); fTestFilePatternFolder.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); fTestFilePatternFolder.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { validateSettings(PREF_TEST_FILE_PATTERN_FOLDER, null, ((Text) e.widget).getText()); } }); Button fTestFilePatternFolderDefaultButton = new Button( testFilePatternGroup, SWT.PUSH); fTestFilePatternFolderDefaultButton.setText("Default"); fTestFilePatternFolderDefaultButton .addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { fTestFilePatternFolder .setText(TEST_FILE_PATTERN_FOLDER_DEFAULT); } }); addInfoLabel( testFilePatternGroup, "The test folder pattern is used for automatic generate the target folder for new test case files", 3); Label sourceFilePatternFolderLabel = new Label(testFilePatternGroup, SWT.NULL); sourceFilePatternFolderLabel.setText("Source Folder Pattern:"); fSourceFilePatternFolder = new Text(testFilePatternGroup, SWT.BORDER | SWT.SINGLE); fSourceFilePatternFolder.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); fSourceFilePatternFolder.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent e) { validateSettings(PREF_SOURCE_FILE_PATTERN_FOLDER, null, ((Text) e.widget).getText()); } }); addInfoLabel( testFilePatternGroup, "The source folder pattern is used for automatic generate the target folder for new php class files", 3); addInfoLabel( testFilePatternGroup, "For both folder pattern use placeholder %p for project and %d[{start,end}] for directory." + "\nExamples for file /library/myframework/subfolder1/subfolder2/filename.php" + "\n%d = /library/myframework/subfolder1/subfolder2" + "\n%d{3} = subfolder1" + "\n%d{2,3} = myframework/subfolder1" + "\n%d{,3} = library/myframework/subfolder1" + "\n%d{2,} = myframework/subfolder1/subfolder2", 3); Label testFilePatternFileLabel = new Label(testFilePatternGroup, SWT.NULL); testFilePatternFileLabel.setText("File Name Pattern:"); fTestFilePatternFile = new Text(testFilePatternGroup, SWT.BORDER | SWT.SINGLE); fTestFilePatternFile.setLayoutData(new GridData( GridData.FILL_HORIZONTAL)); Button fTestFilePatternFileDefaultButton = new Button( testFilePatternGroup, SWT.PUSH); fTestFilePatternFileDefaultButton.setText("Default"); fTestFilePatternFileDefaultButton .addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { fTestFilePatternFile .setText(TEST_FILE_PATTERN_FILE_DEFAULT); } }); addInfoLabel( testFilePatternGroup, "Use placeholder %f for short filename or %ff for long filename without extension and %e for file extension." + "\nExamples for part1.part2.part3.php" + "\n%f = part1" + "\n%ff = part1.part2.part3" + "\n%e = php", 3); return testFilePatternGroup; } private Group createPHPOptionsGroup(Composite folder) { final Group phpUnitOptionsGroup = new Group(folder, SWT.RESIZE); phpUnitOptionsGroup.setText("PHPUnit Options"); final GridLayout phpUnitOptionsLayout = new GridLayout(); phpUnitOptionsLayout.numColumns = 3; phpUnitOptionsLayout.verticalSpacing = 9; phpUnitOptionsGroup.setLayout(phpUnitOptionsLayout); Label fileLabel = new Label(phpUnitOptionsGroup, SWT.NULL); fileLabel.setText("Bootstrap file:"); fBootstrap = new Text(phpUnitOptionsGroup, SWT.BORDER | SWT.SINGLE); fBootstrap.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); fFileButton = new Button(phpUnitOptionsGroup, SWT.PUSH); fFileButton.setText("Browse..."); fFileButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(final SelectionEvent e) { handleBrowse(); } }); fGenerateCodeCoverageCheckbox = new Button(phpUnitOptionsGroup, SWT.CHECK); fGenerateCodeCoverageCheckbox .setText("Generate code coverage (need Xdebug PHP extension)"); fGenerateCodeCoverageCheckbox .setSelection(getBooleanValue(PREF_GENERATE_CODE_COVERAGE)); fGenerateCodeCoverageCheckbox .addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { boolean selection = fGenerateCodeCoverageCheckbox .getSelection(); setValue(PREF_GENERATE_CODE_COVERAGE, selection); } public void widgetDefaultSelected(SelectionEvent e) { } }); GridData data = new GridData(GridData.FILL_HORIZONTAL); data.horizontalSpan = 3; fGenerateCodeCoverageCheckbox.setLayoutData(data); fNoNamespaceCheckCheckbox = new Button(phpUnitOptionsGroup, SWT.CHECK); fNoNamespaceCheckCheckbox .setText("Do not check for equal namespaces while searching for php/test case classes"); fNoNamespaceCheckCheckbox .setSelection(getBooleanValue(PREF_NO_NAMESPACE_CHECK)); fNoNamespaceCheckCheckbox.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { boolean selection = fNoNamespaceCheckCheckbox.getSelection(); setValue(PREF_NO_NAMESPACE_CHECK, selection); } public void widgetDefaultSelected(SelectionEvent e) { } }); data = new GridData(GridData.FILL_HORIZONTAL); data.horizontalSpan = 3; fNoNamespaceCheckCheckbox.setLayoutData(data); return phpUnitOptionsGroup; } private void handleBrowse() { final ResourceSelectionDialog dialog = new ResourceSelectionDialog( getShell(), ResourcesPlugin.getWorkspace().getRoot(), "Select Bootstrap File"); if (dialog.open() == Window.OK) { final Object[] result = dialog.getResult(); if (result.length > 0) { fBootstrap.setText(((IFile) result[0]).getFullPath() .toOSString()); } } } protected void validateSettings(Key changedKey, String oldValue, String newValue) { if (fTestFilePatternFolder.getText().indexOf('{') != -1 && "".equals(fSourceFilePatternFolder.getText())) { String message = "Since you want to use not the whole part for the test folder pattern you have to configure the source folder pattern."; Status status = new Status(IStatus.ERROR, PHPUnitPlugin.PLUGIN_ID, message); getStatusChangeListener().statusChanged(status); } else { getStatusChangeListener().statusChanged(Status.OK_STATUS); } } protected boolean processChanges(IWorkbenchPreferenceContainer container) { clearProjectLauncherCache(PHPUnit.QUALIFIED_NAME); setValue(PREF_BOOSTRAP, fBootstrap.getText()); setValue(PREF_TEST_FILE_PATTERN_FOLDER, fTestFilePatternFolder.getText()); setValue(PREF_TEST_FILE_PATTERN_FILE, fTestFilePatternFile.getText()); setValue(PREF_TEST_FILE_SUPER_CLASS, fTestFileSuperClass.getText()); setValue(PREF_SOURCE_FILE_PATTERN_FOLDER, fSourceFilePatternFolder.getText()); return super.processChanges(container); } public void useProjectSpecificSettings(boolean enable) { super.useProjectSpecificSettings(enable); fBootstrap.setEnabled(enable); fFileButton.setEnabled(enable); } protected String[] getFullBuildDialogStrings(boolean workspaceSettings) { return null; } protected final static Key getPHPUnitKey(String key) { return getKey(PHPUnitPlugin.PLUGIN_ID, key); } protected Key getPHPExecutableKey() { return PREF_PHP_EXECUTABLE; } protected Key getDebugPrintOutputKey() { return PREF_DEBUG_PRINT_OUTPUT; } protected Key getPEARLibraryKey() { return PREF_PEAR_LIBRARY; } /* * (non-Javadoc) * * @seeorg.eclipse.jdt.internal.ui.preferences.OptionsConfigurationBlock# * updateControls() */ protected void updateControls() { super.updateControls(); unpackBootstrap(); unpackTestFilePattern(); } private void unpackBootstrap() { String bootstrap = getValue(PREF_BOOSTRAP); if (bootstrap != null) fBootstrap.setText(bootstrap); } private void unpackTestFilePattern() { String folder = getValue(PREF_TEST_FILE_PATTERN_FOLDER); if (folder == null) folder = TEST_FILE_PATTERN_FOLDER_DEFAULT; fTestFilePatternFolder.setText(folder); String file = getValue(PREF_TEST_FILE_PATTERN_FILE); if (file == null) file = TEST_FILE_PATTERN_FILE_DEFAULT; fTestFilePatternFile.setText(file); String superClass = getValue(PREF_TEST_FILE_SUPER_CLASS); if (superClass == null || "".equals(superClass)) superClass = PHPUnit.PHPUNIT_TEST_CASE_CLASS; fTestFileSuperClass.setText(superClass); folder = getValue(PREF_SOURCE_FILE_PATTERN_FOLDER); if (folder == null) folder = ""; fSourceFilePatternFolder.setText(folder); } }