| /******************************************************************************* |
| * Copyright (c) 2000, 2018 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Johannes Utzig <mail@jutzig.de> - [JUnit] Update test suite wizard for JUnit 4: @RunWith(Suite.class)... - https://bugs.eclipse.org/155828 |
| *******************************************************************************/ |
| package org.eclipse.jdt.junit.wizards; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| 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.Label; |
| |
| import org.eclipse.core.runtime.Assert; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.CheckboxTableViewer; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| |
| import org.eclipse.jface.text.BadLocationException; |
| import org.eclipse.jface.text.Document; |
| import org.eclipse.jface.text.IDocument; |
| |
| import org.eclipse.ui.PlatformUI; |
| |
| import org.eclipse.jdt.core.IAnnotation; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IPackageFragment; |
| import org.eclipse.jdt.core.IPackageFragmentRoot; |
| import org.eclipse.jdt.core.ISourceRange; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.JavaModelException; |
| |
| import org.eclipse.jdt.internal.core.manipulation.StubUtility; |
| import org.eclipse.jdt.internal.corext.util.JavaConventionsUtil; |
| import org.eclipse.jdt.internal.junit.JUnitCorePlugin; |
| import org.eclipse.jdt.internal.junit.Messages; |
| import org.eclipse.jdt.internal.junit.ui.IJUnitHelpContextIds; |
| import org.eclipse.jdt.internal.junit.util.CoreTestSearchEngine; |
| import org.eclipse.jdt.internal.junit.util.JUnitStatus; |
| import org.eclipse.jdt.internal.junit.util.JUnitStubUtility; |
| import org.eclipse.jdt.internal.junit.util.LayoutUtil; |
| import org.eclipse.jdt.internal.junit.wizards.SuiteClassesContentProvider; |
| import org.eclipse.jdt.internal.junit.wizards.TestSuiteClassListRange; |
| import org.eclipse.jdt.internal.junit.wizards.UpdateTestSuite; |
| import org.eclipse.jdt.internal.junit.wizards.WizardMessages; |
| |
| import org.eclipse.jdt.ui.JavaElementLabelProvider; |
| import org.eclipse.jdt.ui.wizards.NewTypeWizardPage; |
| |
| /** |
| * The class <code>NewTestSuiteWizardPage</code> contains controls and validation routines |
| * for the single page in the 'New JUnit TestSuite Wizard'. |
| * <p> |
| * Clients can use the page as-is and add it to their own wizard, or extend it to modify |
| * validation or add and remove controls. |
| * </p> |
| * |
| * @since 3.1 |
| */ |
| public class NewTestSuiteWizardPage extends NewTypeWizardPage { |
| |
| private static final String ALL_TESTS= "AllTests"; //$NON-NLS-1$ |
| |
| public static final String NON_COMMENT_END_MARKER = "$JUnit-END$"; //$NON-NLS-1$ |
| |
| public static final String NON_COMMENT_START_MARKER = "$JUnit-BEGIN$"; //$NON-NLS-1$ |
| |
| public static final String COMMENT_START = "//"; //$NON-NLS-1$ |
| |
| /** |
| * The string used to mark the beginning of the generated code |
| */ |
| public static final String START_MARKER= COMMENT_START + NON_COMMENT_START_MARKER; |
| |
| /** |
| * The string used to mark the end of the generated code |
| */ |
| public static final String END_MARKER= COMMENT_START + NON_COMMENT_END_MARKER; |
| |
| private final static String PAGE_NAME= "NewTestSuiteCreationWizardPage"; //$NON-NLS-1$ |
| |
| /** Field ID of the class in suite field. */ |
| public final static String CLASSES_IN_SUITE= PAGE_NAME + ".classesinsuite"; //$NON-NLS-1$ |
| |
| /** |
| * Field ID of the junit4 toggle field. |
| * |
| * @since 3.7 |
| */ |
| public final static String JUNIT4TOGGLE= PAGE_NAME + ".junit4toggle"; //$NON-NLS-1$ |
| |
| private CheckboxTableViewer fClassesInSuiteTable; |
| private IStatus fClassesInSuiteStatus; |
| |
| private Label fSelectedClassesLabel; |
| |
| private boolean fUpdatedExistingClassButton; |
| |
| private Button fJUnit4Toggle; |
| private Button fJUnit3Toggle; |
| private boolean fIsJunit4; |
| private boolean fIsJunit4Enabled; |
| |
| /** |
| * Creates a new <code>NewTestSuiteWizardPage</code>. |
| */ |
| public NewTestSuiteWizardPage() { |
| super(true, PAGE_NAME); |
| setTitle(WizardMessages.NewTestSuiteWizPage_title); |
| setDescription(WizardMessages.NewTestSuiteWizPage_description); |
| |
| fClassesInSuiteStatus= new JUnitStatus(); |
| } |
| |
| @Override |
| public void createControl(Composite parent) { |
| initializeDialogUnits(parent); |
| |
| Composite composite= new Composite(parent, SWT.NONE); |
| int nColumns= 4; |
| |
| GridLayout layout= new GridLayout(); |
| layout.numColumns= nColumns; |
| composite.setLayout(layout); |
| createJUnit4Controls(composite, nColumns); |
| createContainerControls(composite, nColumns); |
| createPackageControls(composite, nColumns); |
| //createSeparator(composite, nColumns); |
| createTypeNameControls(composite, nColumns); |
| createClassesInSuiteControl(composite, nColumns); |
| createMethodStubSelectionControls(composite, nColumns); |
| setControl(composite); |
| restoreWidgetValues(); |
| Dialog.applyDialogFont(composite); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJUnitHelpContextIds.NEW_TESTSUITE_WIZARD_PAGE); |
| } |
| |
| /** |
| * Creates the controls for the method stub selection buttons. Expects a <code>GridLayout</code> with |
| * at least 3 columns. |
| * |
| * @param composite the parent composite |
| * @param nColumns number of columns to span |
| */ |
| protected void createMethodStubSelectionControls(Composite composite, int nColumns) { |
| } |
| |
| /** |
| * Should be called from the wizard with the initial selection. |
| * |
| * @param selection the initial selection |
| */ |
| public void init(IStructuredSelection selection) { |
| IJavaElement jelem= getInitialJavaElement(selection); |
| initContainerPage(jelem, true); |
| initSuitePage(jelem); |
| boolean isJunit4= false; |
| if (jelem != null && jelem.getElementType() != IJavaElement.JAVA_MODEL) { |
| IJavaProject project= jelem.getJavaProject(); |
| isJunit4= CoreTestSearchEngine.hasJUnit4TestAnnotation(project); |
| if (!isJunit4 && !CoreTestSearchEngine.hasTestCaseType(project) && JUnitStubUtility.is50OrHigher(project)) { |
| isJunit4= true; |
| } |
| } |
| setJUnit4(isJunit4, true); |
| doStatusUpdate(); |
| } |
| |
| private void initSuitePage(IJavaElement jelem) { |
| //parts of NewTypeWizardPage#initTypePage(..), see bug 132748 |
| |
| if (jelem != null) { |
| IPackageFragment pack= (IPackageFragment) jelem.getAncestor(IJavaElement.PACKAGE_FRAGMENT); |
| IJavaProject project= jelem.getJavaProject(); |
| |
| setPackageFragment(pack, true); |
| setAddComments(StubUtility.doAddComments(project), true); // from project or workspace |
| } |
| |
| setTypeName(ALL_TESTS, true); |
| fTypeNameStatus= typeNameChanged(); //set status on initialization for this dialog - user must know that suite method will be overridden |
| } |
| |
| @Override |
| protected void handleFieldChanged(String fieldName) { |
| super.handleFieldChanged(fieldName); |
| if (PACKAGE.equals(fieldName) || CONTAINER.equals(fieldName) || JUNIT4TOGGLE.equals(fieldName)) { |
| updateClassesInSuiteTable(); |
| } else if (CLASSES_IN_SUITE.equals(fieldName)) { |
| fClassesInSuiteStatus= classesInSuiteChanged(); |
| fTypeNameStatus= typeNameChanged(); //must check this one too |
| updateSelectedClassesLabel(); |
| } |
| |
| doStatusUpdate(); |
| } |
| |
| // ------ validation -------- |
| private void doStatusUpdate() { |
| // status of all used components |
| IStatus[] status= new IStatus[] { |
| fContainerStatus, |
| fPackageStatus, |
| fTypeNameStatus, |
| fClassesInSuiteStatus |
| }; |
| |
| // the most severe status will be displayed and the OK button enabled/disabled. |
| updateStatus(status); |
| } |
| |
| @Override |
| public void setVisible(boolean visible) { |
| if (visible) { |
| setFocus(); |
| updateClassesInSuiteTable(); |
| handleAllFieldsChanged(); |
| } else { |
| saveWidgetValues(); |
| } |
| super.setVisible(visible); |
| } |
| |
| private void handleAllFieldsChanged() { |
| handleFieldChanged(PACKAGE); |
| handleFieldChanged(CONTAINER); |
| handleFieldChanged(CLASSES_IN_SUITE); |
| handleFieldChanged(TYPENAME); |
| } |
| |
| /** |
| * Updates the classes in the suite table. |
| */ |
| protected void updateClassesInSuiteTable() { |
| if (fClassesInSuiteTable != null) { |
| IPackageFragment pack= getPackageFragment(); |
| if (pack == null) { |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| if (root != null) |
| pack= root.getPackageFragment(""); //$NON-NLS-1$ |
| else |
| return; |
| } |
| fClassesInSuiteTable.setInput(pack); |
| fClassesInSuiteTable.setAllChecked(true); |
| updateSelectedClassesLabel(); |
| } |
| } |
| |
| /** |
| * Creates the controls for the list of classes in the suite. Expects a <code>GridLayout</code> with |
| * at least 3 columns. |
| * |
| * @param parent the parent composite |
| * @param nColumns number of columns to span |
| */ |
| protected void createClassesInSuiteControl(Composite parent, int nColumns) { |
| if (fClassesInSuiteTable == null) { |
| |
| Label label = new Label(parent, SWT.LEFT); |
| label.setText(WizardMessages.NewTestSuiteWizPage_classes_in_suite_label); |
| GridData gd= new GridData(); |
| gd.horizontalAlignment = GridData.FILL; |
| gd.horizontalSpan= nColumns; |
| label.setLayoutData(gd); |
| |
| fClassesInSuiteTable= CheckboxTableViewer.newCheckList(parent, SWT.BORDER); |
| gd= new GridData(GridData.FILL_BOTH); |
| gd.heightHint= 80; |
| gd.horizontalSpan= nColumns-1; |
| |
| fClassesInSuiteTable.getTable().setLayoutData(gd); |
| fClassesInSuiteTable.setContentProvider(new SuiteClassesContentProvider(isJUnit4())); |
| fClassesInSuiteTable.setLabelProvider(new JavaElementLabelProvider()); |
| fClassesInSuiteTable.addCheckStateListener(event -> handleFieldChanged(CLASSES_IN_SUITE)); |
| |
| Composite buttonContainer= new Composite(parent, SWT.NONE); |
| gd= new GridData(GridData.FILL_VERTICAL); |
| buttonContainer.setLayoutData(gd); |
| GridLayout buttonLayout= new GridLayout(); |
| buttonLayout.marginWidth= 0; |
| buttonLayout.marginHeight= 0; |
| buttonContainer.setLayout(buttonLayout); |
| |
| Button selectAllButton= new Button(buttonContainer, SWT.PUSH); |
| selectAllButton.setText(WizardMessages.NewTestSuiteWizPage_selectAll); |
| GridData bgd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); |
| bgd.widthHint = LayoutUtil.getButtonWidthHint(selectAllButton); |
| selectAllButton.setLayoutData(bgd); |
| selectAllButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| fClassesInSuiteTable.setAllChecked(true); |
| handleFieldChanged(CLASSES_IN_SUITE); |
| } |
| }); |
| |
| Button deselectAllButton= new Button(buttonContainer, SWT.PUSH); |
| deselectAllButton.setText(WizardMessages.NewTestSuiteWizPage_deselectAll); |
| bgd= new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_BEGINNING); |
| bgd.widthHint = LayoutUtil.getButtonWidthHint(deselectAllButton); |
| deselectAllButton.setLayoutData(bgd); |
| deselectAllButton.addSelectionListener(new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| fClassesInSuiteTable.setAllChecked(false); |
| handleFieldChanged(CLASSES_IN_SUITE); |
| } |
| }); |
| |
| // No of selected classes label |
| fSelectedClassesLabel= new Label(parent, SWT.LEFT | SWT.WRAP); |
| fSelectedClassesLabel.setFont(parent.getFont()); |
| updateSelectedClassesLabel(); |
| gd = new GridData(); |
| gd.horizontalSpan = 2; |
| fSelectedClassesLabel.setLayoutData(gd); |
| } |
| } |
| |
| |
| @Override |
| protected void createTypeMembers(IType type, ImportsManager imports, IProgressMonitor monitor) throws CoreException { |
| writeImports(imports); |
| if(!isJUnit4()) |
| type.createMethod(getSuiteMethodString(type), null, false, null); |
| } |
| |
| /* |
| * Returns the string content for creating a new suite() method. |
| */ |
| private String getSuiteMethodString(IType type) { |
| String typeName= type.getElementName(); |
| StringBuilder suite= new StringBuilder("public static Test suite () {TestSuite suite= new TestSuite(" + typeName + ".class.getName());\n"); //$NON-NLS-1$ //$NON-NLS-2$ |
| suite.append(getUpdatableString()); |
| suite.append("\nreturn suite;}"); //$NON-NLS-1$ |
| return suite.toString(); |
| } |
| |
| private String getUpdatableString() { |
| return UpdateTestSuite.getUpdatableString(fClassesInSuiteTable.getCheckedElements()); |
| } |
| |
| @Override |
| public void createType(IProgressMonitor monitor) throws CoreException, InterruptedException { |
| IPackageFragment pack= getPackageFragment(); |
| ICompilationUnit cu= pack.getCompilationUnit(getTypeName() + ".java"); //$NON-NLS-1$ |
| |
| if (!cu.exists()) { |
| super.createType(monitor); |
| fUpdatedExistingClassButton= false; |
| } else { |
| updateExistingType(cu, monitor); |
| fUpdatedExistingClassButton= true; |
| } |
| } |
| |
| private void updateExistingType(ICompilationUnit cu, IProgressMonitor monitor) throws JavaModelException { |
| if (!UpdateTestSuite.checkValidateEditStatus(cu, getShell())) |
| return; |
| IType suiteType= cu.getType(getTypeName()); |
| monitor.beginTask(WizardMessages.NewTestSuiteWizPage_createType_beginTask, 10); |
| if (isJUnit4()) { |
| /* find TestClasses already in Test Suite */ |
| IAnnotation suiteClasses= suiteType.getAnnotation("SuiteClasses"); //$NON-NLS-1$ |
| if (suiteClasses.exists()) { |
| UpdateTestSuite.updateTestCasesInJunit4Suite(new SubProgressMonitor(monitor, 5), cu, suiteClasses, fClassesInSuiteTable.getCheckedElements()); |
| } else { |
| cannotUpdateSuiteError(); |
| } |
| } else { |
| |
| IMethod suiteMethod= suiteType.getMethod("suite", new String[] {}); //$NON-NLS-1$ |
| monitor.worked(1); |
| String lineDelimiter= cu.findRecommendedLineSeparator(); |
| if (suiteMethod.exists()) { |
| ISourceRange range= suiteMethod.getSourceRange(); |
| if (range != null) { |
| try { |
| IDocument fullSource= new Document(cu.getBuffer().getContents()); |
| String originalContent= fullSource.get(range.getOffset(), range.getLength()); |
| TestSuiteClassListRange classListRange= UpdateTestSuite.getTestSuiteClassListRange(originalContent); |
| if (classListRange != null) { |
| UpdateTestSuite.updateTestCasesInSuite(monitor, cu, suiteMethod, fClassesInSuiteTable.getCheckedElements()); |
| } else { |
| cannotUpdateSuiteError(); |
| } |
| } catch (BadLocationException e) { |
| Assert.isTrue(false, "Should never happen"); //$NON-NLS-1$ |
| } |
| } else { |
| MessageDialog.openError(getShell(), WizardMessages.NewTestSuiteWizPage_createType_updateErrorDialog_title, WizardMessages.NewTestSuiteWizPage_createType_updateErrorDialog_message); |
| } |
| } else { |
| suiteType.createMethod(getSuiteMethodString(suiteType), null, true, monitor); |
| String originalContent= cu.getSource(); |
| monitor.worked(2); |
| String formattedContent= JUnitStubUtility.formatCompilationUnit(cu.getJavaProject(), originalContent, lineDelimiter); |
| cu.getBuffer().setContents(formattedContent); |
| monitor.worked(1); |
| cu.save(new SubProgressMonitor(monitor, 1), false); |
| } |
| |
| } |
| |
| monitor.done(); |
| } |
| |
| /** |
| * Returns true iff an existing suite() method has been replaced. |
| * |
| * @return <code>true</code> is returned if an existing test suite has been replaced |
| */ |
| public boolean hasUpdatedExistingClass() { |
| return fUpdatedExistingClassButton; |
| } |
| |
| private IStatus classesInSuiteChanged() { |
| JUnitStatus status= new JUnitStatus(); |
| if (fClassesInSuiteTable.getCheckedElements().length <= 0) |
| status.setWarning(WizardMessages.NewTestSuiteWizPage_classes_in_suite_error_no_testclasses_selected); |
| return status; |
| } |
| |
| private void updateSelectedClassesLabel() { |
| int noOfClassesChecked= fClassesInSuiteTable.getCheckedElements().length; |
| String key= (noOfClassesChecked==1) ? WizardMessages.NewTestClassWizPage_treeCaption_classSelected : WizardMessages.NewTestClassWizPage_treeCaption_classesSelected; |
| fSelectedClassesLabel.setText(Messages.format(key, Integer.valueOf(noOfClassesChecked))); |
| } |
| |
| |
| @Override |
| protected IStatus typeNameChanged() { |
| super.typeNameChanged(); |
| |
| JUnitStatus status= new JUnitStatus(); |
| String typeName= getTypeName(); |
| // must not be empty |
| if (typeName.length() == 0) { |
| status.setError(WizardMessages.NewTestSuiteWizPage_typeName_error_name_empty); |
| return status; |
| } |
| if (typeName.indexOf('.') != -1) { |
| status.setError(WizardMessages.NewTestSuiteWizPage_typeName_error_name_qualified); |
| return status; |
| } |
| |
| IPackageFragment pack= getPackageFragment(); |
| if (pack != null) { |
| ICompilationUnit cu= pack.getCompilationUnit(typeName + ".java"); //$NON-NLS-1$ |
| //if this cu already exists, we need to disable the |
| //junit 3 option if it is a junit 4 suite and vice versa |
| if (cu.exists()) { |
| IType type= cu.findPrimaryType(); |
| if (type != null) { |
| setJUnit4(type.getAnnotation("RunWith").exists(), false); //$NON-NLS-1$ |
| } |
| } else { |
| setJUnit4(isJUnit4(), true); |
| } |
| } |
| |
| IStatus val= JavaConventionsUtil.validateJavaTypeName(typeName, getJavaProject()); |
| if (val.getSeverity() == IStatus.ERROR) { |
| status.setError(WizardMessages.NewTestSuiteWizPage_typeName_error_name_not_valid+val.getMessage()); |
| return status; |
| } else if (val.getSeverity() == IStatus.WARNING) { |
| status.setWarning(WizardMessages.NewTestSuiteWizPage_typeName_error_name_name_discouraged+val.getMessage()); |
| // continue checking |
| } |
| |
| IStatus recursiveSuiteInclusionStatus= checkRecursiveTestSuiteInclusion(); |
| if (! recursiveSuiteInclusionStatus.isOK()) |
| return recursiveSuiteInclusionStatus; |
| |
| if (pack != null) { |
| ICompilationUnit cu= pack.getCompilationUnit(typeName + ".java"); //$NON-NLS-1$ |
| if (cu.exists()) { |
| status.setWarning(isJUnit4() |
| ? WizardMessages.NewTestSuiteWizPage_typeName_warning_already_exists_junit4 |
| : WizardMessages.NewTestSuiteWizPage_typeName_warning_already_exists); |
| return status; |
| } |
| IResource resource= cu.getResource(); |
| if (resource != null && !ResourcesPlugin.getWorkspace().validateFiltered(resource).isOK()) { |
| status.setError(WizardMessages.NewTestSuiteWizPage_typeName_error_filtered); |
| return status; |
| } |
| } |
| return status; |
| } |
| |
| private IStatus checkRecursiveTestSuiteInclusion(){ |
| if (fClassesInSuiteTable == null) |
| return new JUnitStatus(); |
| String typeName= getTypeName(); |
| JUnitStatus status= new JUnitStatus(); |
| Object[] checkedClasses= fClassesInSuiteTable.getCheckedElements(); |
| for (Object checkedClass : checkedClasses) { |
| if (((IType)checkedClass).getElementName().equals(typeName)){ |
| status.setWarning(WizardMessages.NewTestSuiteCreationWizardPage_infinite_recursion); |
| return status; |
| } |
| } |
| return new JUnitStatus(); |
| } |
| |
| |
| private void cannotUpdateSuiteError() { |
| MessageDialog.openError(getShell(), WizardMessages.NewTestSuiteWizPage_cannotUpdateDialog_title, |
| Messages.format(WizardMessages.NewTestSuiteWizPage_cannotUpdateDialog_message, new String[] { NewTestSuiteWizardPage.START_MARKER, NewTestSuiteWizardPage.END_MARKER})); |
| |
| } |
| |
| private void writeImports(ImportsManager imports) { |
| if (isJUnit4()) { |
| imports.addImport("org.junit.runner.RunWith"); //$NON-NLS-1$ |
| imports.addImport("org.junit.runners.Suite"); //$NON-NLS-1$ |
| imports.addImport("org.junit.runners.Suite.SuiteClasses"); //$NON-NLS-1$ |
| } else { |
| imports.addImport("junit.framework.Test"); //$NON-NLS-1$ |
| imports.addImport("junit.framework.TestSuite"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Use the dialog store to restore widget values to the values that they held |
| * last time this wizard was used to completion |
| */ |
| private void restoreWidgetValues() { |
| } |
| |
| /** |
| * Since Finish was pressed, write widget values to the dialog store so that they |
| * will persist into the next invocation of this wizard page |
| */ |
| private void saveWidgetValues() { |
| } |
| |
| |
| |
| /** |
| * Creates the controls for the JUnit 4 toggle control. Expects a <code>GridLayout</code> with |
| * at least 3 columns. |
| * |
| * @param composite the parent composite |
| * @param nColumns number of columns to span |
| * |
| * @since 3.7 |
| */ |
| protected void createJUnit4Controls(Composite composite, int nColumns) { |
| Composite inner= new Composite(composite, SWT.NONE); |
| inner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, nColumns, 1)); |
| GridLayout layout= new GridLayout(2, false); |
| layout.marginHeight= 0; |
| layout.marginWidth= 0; |
| inner.setLayout(layout); |
| |
| SelectionAdapter listener= new SelectionAdapter() { |
| @Override |
| public void widgetSelected(SelectionEvent e) { |
| boolean isSelected= ((Button) e.widget).getSelection(); |
| internalSetJUnit4(isSelected); |
| } |
| }; |
| |
| fJUnit3Toggle = new Button(inner, SWT.RADIO); |
| fJUnit3Toggle.setText(WizardMessages.NewTestClassWizPage_junit3_radio_label); |
| fJUnit3Toggle.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 1, 1)); |
| fJUnit3Toggle.setSelection(!fIsJunit4); |
| fJUnit3Toggle.setEnabled(fIsJunit4Enabled); |
| |
| fJUnit4Toggle= new Button(inner, SWT.RADIO); |
| fJUnit4Toggle.setText(WizardMessages.NewTestClassWizPage_junit4_radio_label); |
| fJUnit4Toggle.setSelection(fIsJunit4); |
| fJUnit4Toggle.setEnabled(fIsJunit4Enabled); |
| fJUnit4Toggle.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, false, false, 1, 1)); |
| fJUnit4Toggle.addSelectionListener(listener); |
| } |
| |
| /** |
| * Specifies if the test should be created as JUnit 4 test. |
| * |
| * @param isJUnit4 If set, a JUnit 4 test will be created |
| * @param isEnabled if <code>true</code> the modifier fields are |
| * editable; otherwise they are read-only |
| * |
| * @since 3.7 |
| */ |
| public void setJUnit4(boolean isJUnit4, boolean isEnabled) { |
| fIsJunit4Enabled= isEnabled; |
| if (fJUnit4Toggle != null && !fJUnit4Toggle.isDisposed()) { |
| fJUnit4Toggle.setSelection(isJUnit4); |
| fJUnit3Toggle.setSelection(!isJUnit4); |
| fJUnit4Toggle.setEnabled(isEnabled || isJUnit4); |
| fJUnit3Toggle.setEnabled(isEnabled || !isJUnit4); |
| } |
| internalSetJUnit4(isJUnit4); |
| } |
| |
| /** |
| * Returns <code>true</code> if the test suite should be created as Junit 4 suite |
| * @return returns <code>true</code> if the test suite should be created as Junit 4 test |
| * |
| * @since 3.7 |
| */ |
| public boolean isJUnit4() { |
| return fIsJunit4; |
| } |
| |
| private void internalSetJUnit4(boolean isJUnit4) { |
| if (fIsJunit4 == isJUnit4) |
| return; |
| fIsJunit4= isJUnit4; |
| if (fClassesInSuiteTable != null && fClassesInSuiteTable.getContentProvider() instanceof SuiteClassesContentProvider) { |
| SuiteClassesContentProvider provider= (SuiteClassesContentProvider)fClassesInSuiteTable.getContentProvider(); |
| provider.setIncludeJunit4Tests(isJUnit4); |
| } |
| if (fIsJunit4) { |
| setSuperClass("java.lang.Object", false); //$NON-NLS-1$ |
| } else { |
| setSuperClass(JUnitCorePlugin.TEST_SUPERCLASS_NAME, true); |
| } |
| handleFieldChanged(JUNIT4TOGGLE); |
| } |
| |
| @Override |
| protected String constructCUContent(ICompilationUnit cu, String typeContent, String lineDelimiter) throws CoreException { |
| if (isJUnit4()) { |
| typeContent= appendAnnotations(typeContent, lineDelimiter); |
| } |
| |
| return super.constructCUContent(cu, typeContent, lineDelimiter); |
| } |
| |
| private String appendAnnotations(String typeContent, String lineDelimiter) { |
| Object[] checkedElements= fClassesInSuiteTable.getCheckedElements(); |
| StringBuilder buffer = new StringBuilder("@RunWith(Suite.class)"); //$NON-NLS-1$ |
| buffer.append(lineDelimiter); |
| buffer.append("@SuiteClasses({"); //$NON-NLS-1$ |
| for (int i= 0; i < checkedElements.length; i++) { |
| if (checkedElements[i] instanceof IType) { |
| IType testType= (IType) checkedElements[i]; |
| buffer.append(testType.getElementName()); |
| buffer.append(".class"); //$NON-NLS-1$ |
| if(i<checkedElements.length-1) |
| buffer.append(','); |
| |
| } |
| } |
| buffer.append("})"); //$NON-NLS-1$ |
| buffer.append(lineDelimiter); |
| buffer.append(typeContent); |
| return buffer.toString(); |
| } |
| } |