| /******************************************************************************* |
| * Copyright (c) 2000, 2005 IBM Corporation and others. |
| * 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 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Sebastian Davids - bug 38507 & 113998 |
| *******************************************************************************/ |
| package org.eclipse.jdt.junit.wizards; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.List; |
| import java.util.ListIterator; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.events.ModifyListener; |
| 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.Label; |
| import org.eclipse.swt.widgets.Text; |
| |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.viewers.IStructuredSelection; |
| import org.eclipse.jface.window.Window; |
| |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.SelectionDialog; |
| |
| import org.eclipse.jdt.core.IClassFile; |
| 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.IType; |
| import org.eclipse.jdt.core.ITypeHierarchy; |
| import org.eclipse.jdt.core.JavaConventions; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.core.search.IJavaSearchScope; |
| import org.eclipse.jdt.core.search.SearchEngine; |
| |
| import org.eclipse.jdt.ui.CodeGeneration; |
| import org.eclipse.jdt.ui.IJavaElementSearchConstants; |
| import org.eclipse.jdt.ui.JavaElementLabels; |
| import org.eclipse.jdt.ui.JavaUI; |
| import org.eclipse.jdt.ui.wizards.NewTypeWizardPage; |
| |
| import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper; |
| import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaTypeCompletionProcessor; |
| |
| import org.eclipse.jdt.internal.junit.Messages; |
| import org.eclipse.jdt.internal.junit.ui.IJUnitHelpContextIds; |
| import org.eclipse.jdt.internal.junit.ui.JUnitAddLibraryProposal; |
| import org.eclipse.jdt.internal.junit.ui.JUnitPlugin; |
| 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.util.TestSearchEngine; |
| import org.eclipse.jdt.internal.junit.util.JUnitStubUtility.GenStubSettings; |
| import org.eclipse.jdt.internal.junit.wizards.MethodStubsSelectionButtonGroup; |
| import org.eclipse.jdt.internal.junit.wizards.WizardMessages; |
| |
| /** |
| * The class <code>NewTestCaseWizardPageOne</code> contains controls and validation routines |
| * for the first page of the 'New JUnit TestCase Wizard'. |
| * |
| * 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. |
| * |
| * @since 3.1 |
| */ |
| public class NewTestCaseWizardPageOne extends NewTypeWizardPage { |
| |
| private final static String PAGE_NAME= "NewTestCaseCreationWizardPage"; //$NON-NLS-1$ |
| |
| |
| /** Field ID of the class under test field. */ |
| public final static String CLASS_UNDER_TEST= PAGE_NAME + ".classundertest"; //$NON-NLS-1$ |
| |
| private final static String QUESTION_MARK_TAG= "Q"; //$NON-NLS-1$ |
| private final static String OF_TAG= "Of"; //$NON-NLS-1$ |
| |
| private final static String TEST_SUFFIX= "Test"; //$NON-NLS-1$ |
| private final static String SETUP= "setUp"; //$NON-NLS-1$ |
| private final static String TEARDOWN= "tearDown"; //$NON-NLS-1$ |
| private final static String PREFIX= "test"; //$NON-NLS-1$ |
| |
| private final static String STORE_GENERATE_MAIN= PAGE_NAME + ".GENERATE_MAIN"; //$NON-NLS-1$ |
| private final static String STORE_USE_TESTRUNNER= PAGE_NAME + ".USE_TESTRUNNER"; //$NON-NLS-1$ |
| private final static String STORE_TESTRUNNER_TYPE= PAGE_NAME + ".TESTRUNNER_TYPE"; //$NON-NLS-1$ |
| |
| private NewTestCaseWizardPageTwo fPage2; |
| private MethodStubsSelectionButtonGroup fMethodStubsButtons; |
| |
| private String fClassUnderTestText; // model |
| private IType fClassUnderTest; // resolved model, can be null |
| |
| private Text fClassUnderTestControl; // control |
| private IStatus fClassUnderTestStatus; // status |
| |
| private Button fClassUnderTestButton; |
| private JavaTypeCompletionProcessor fClassToTestCompletionProcessor; |
| |
| /** |
| * Creates a new <code>NewTestCaseCreationWizardPage</code>. |
| * @param page2 The second page |
| * |
| * @since 3.1 |
| */ |
| public NewTestCaseWizardPageOne(NewTestCaseWizardPageTwo page2) { |
| super(true, PAGE_NAME); |
| fPage2= page2; |
| |
| setTitle(WizardMessages.NewTestCaseWizardPageOne_title); |
| setDescription(WizardMessages.NewTestCaseWizardPageOne_description); |
| |
| String[] buttonNames= new String[] { |
| "&public static void main(String[] args)", //$NON-NLS-1$ |
| WizardMessages.NewTestCaseWizardPageOne_methodStub_testRunner, |
| WizardMessages.NewTestCaseWizardPageOne_methodStub_setUp, |
| WizardMessages.NewTestCaseWizardPageOne_methodStub_tearDown, |
| WizardMessages.NewTestCaseWizardPageOne_methodStub_constructor |
| }; |
| |
| fMethodStubsButtons= new MethodStubsSelectionButtonGroup(SWT.CHECK, buttonNames, 1); |
| fMethodStubsButtons.setLabelText(WizardMessages.NewTestCaseWizardPageOne_method_Stub_label); |
| |
| fClassToTestCompletionProcessor= new JavaTypeCompletionProcessor(false, false); |
| |
| fClassUnderTestStatus= new JUnitStatus(); |
| |
| fClassUnderTestText= ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Initialized the page with the current selection |
| * @param selection The selection |
| */ |
| public void init(IStructuredSelection selection) { |
| IJavaElement element= getInitialJavaElement(selection); |
| |
| initContainerPage(element); |
| initTypePage(element); |
| // put default class to test |
| if (element != null) { |
| IType classToTest= null; |
| // evaluate the enclosing type |
| IType typeInCompUnit= (IType) element.getAncestor(IJavaElement.TYPE); |
| if (typeInCompUnit != null) { |
| if (typeInCompUnit.getCompilationUnit() != null) { |
| classToTest= typeInCompUnit; |
| } |
| } else { |
| ICompilationUnit cu= (ICompilationUnit) element.getAncestor(IJavaElement.COMPILATION_UNIT); |
| if (cu != null) |
| classToTest= cu.findPrimaryType(); |
| else { |
| if (element instanceof IClassFile) { |
| try { |
| IClassFile cf= (IClassFile) element; |
| if (cf.isStructureKnown()) |
| classToTest= cf.getType(); |
| } catch(JavaModelException e) { |
| JUnitPlugin.log(e); |
| } |
| } |
| } |
| } |
| if (classToTest != null) { |
| try { |
| if (!TestSearchEngine.isTestImplementor(classToTest)) { |
| setClassUnderTest(classToTest.getFullyQualifiedName('.')); |
| } |
| } catch (JavaModelException e) { |
| JUnitPlugin.log(e); |
| } |
| } |
| } |
| fMethodStubsButtons.setSelection(0, false); //main |
| fMethodStubsButtons.setSelection(1, false); //add textrunner |
| fMethodStubsButtons.setEnabled(1, false); //add text |
| fMethodStubsButtons.setSelection(2, false); //setUp |
| fMethodStubsButtons.setSelection(3, false); //tearDown |
| fMethodStubsButtons.setSelection(4, false); //constructor |
| |
| updateStatus(getStatusList()); |
| } |
| |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.ui.wizards.NewContainerWizardPage#handleFieldChanged(String) |
| */ |
| protected void handleFieldChanged(String fieldName) { |
| super.handleFieldChanged(fieldName); |
| if (fieldName.equals(CONTAINER)) { |
| fClassUnderTestStatus= classUnderTestChanged(); |
| if (fClassUnderTestButton != null && !fClassUnderTestButton.isDisposed()) { |
| fClassUnderTestButton.setEnabled(getPackageFragmentRoot() != null); |
| } |
| } |
| updateStatus(getStatusList()); |
| } |
| |
| /** |
| * Returns all status to be consider for the validation. Clients can override. |
| * @return The list of status to consider for the validation. |
| */ |
| protected IStatus[] getStatusList() { |
| return new IStatus[] { |
| fContainerStatus, |
| fPackageStatus, |
| fTypeNameStatus, |
| fClassUnderTestStatus, |
| fModifierStatus, |
| fSuperClassStatus |
| }; |
| } |
| |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) |
| */ |
| 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); |
| |
| createContainerControls(composite, nColumns); |
| createPackageControls(composite, nColumns); |
| createSeparator(composite, nColumns); |
| createTypeNameControls(composite, nColumns); |
| createSuperClassControls(composite, nColumns); |
| createMethodStubSelectionControls(composite, nColumns); |
| setSuperClass(JUnitPlugin.TEST_SUPERCLASS_NAME, true); |
| createSeparator(composite, nColumns); |
| createClassUnderTestControls(composite, nColumns); |
| |
| setControl(composite); |
| |
| //set default and focus |
| String classUnderTest= getClassUnderTestText(); |
| if (classUnderTest.length() > 0) { |
| setTypeName(Signature.getSimpleName(classUnderTest)+TEST_SUFFIX, true); |
| } |
| restoreWidgetValues(); |
| Dialog.applyDialogFont(composite); |
| PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IJUnitHelpContextIds.NEW_TESTCASE_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) { |
| LayoutUtil.setHorizontalSpan(fMethodStubsButtons.getLabelControl(composite), nColumns); |
| LayoutUtil.createEmptySpace(composite, 1); |
| LayoutUtil.setHorizontalSpan(fMethodStubsButtons.getSelectionButtonsGroup(composite), nColumns - 1); |
| } |
| |
| /** |
| * Creates the controls for the 'class under test' field. Expects a <code>GridLayout</code> with |
| * at least 3 columns. |
| * |
| * @param composite the parent composite |
| * @param nColumns number of columns to span |
| */ |
| protected void createClassUnderTestControls(Composite composite, int nColumns) { |
| Label classUnderTestLabel= new Label(composite, SWT.LEFT | SWT.WRAP); |
| classUnderTestLabel.setFont(composite.getFont()); |
| classUnderTestLabel.setText(WizardMessages.NewTestCaseWizardPageOne_class_to_test_label); |
| classUnderTestLabel.setLayoutData(new GridData()); |
| |
| fClassUnderTestControl= new Text(composite, SWT.SINGLE | SWT.BORDER); |
| fClassUnderTestControl.setEnabled(true); |
| fClassUnderTestControl.setFont(composite.getFont()); |
| fClassUnderTestControl.setText(fClassUnderTestText); |
| fClassUnderTestControl.addModifyListener(new ModifyListener() { |
| public void modifyText(ModifyEvent e) { |
| internalSetClassUnderText(((Text) e.widget).getText()); |
| } |
| }); |
| GridData gd= new GridData(); |
| gd.horizontalAlignment= GridData.FILL; |
| gd.grabExcessHorizontalSpace= true; |
| gd.horizontalSpan= nColumns - 2; |
| fClassUnderTestControl.setLayoutData(gd); |
| |
| fClassUnderTestButton= new Button(composite, SWT.PUSH); |
| fClassUnderTestButton.setText(WizardMessages.NewTestCaseWizardPageOne_class_to_test_browse); |
| fClassUnderTestButton.setEnabled(true); |
| fClassUnderTestButton.addSelectionListener(new SelectionListener() { |
| public void widgetDefaultSelected(SelectionEvent e) { |
| classToTestButtonPressed(); |
| } |
| public void widgetSelected(SelectionEvent e) { |
| classToTestButtonPressed(); |
| } |
| }); |
| gd= new GridData(); |
| gd.horizontalAlignment= GridData.FILL; |
| gd.grabExcessHorizontalSpace= false; |
| gd.horizontalSpan= 1; |
| gd.widthHint = LayoutUtil.getButtonWidthHint(fClassUnderTestButton); |
| fClassUnderTestButton.setLayoutData(gd); |
| |
| ControlContentAssistHelper.createTextContentAssistant(fClassUnderTestControl, fClassToTestCompletionProcessor); |
| setFocus(); |
| } |
| |
| private void classToTestButtonPressed() { |
| IType type= chooseClassToTestType(); |
| if (type != null) { |
| setClassUnderTest(type.getFullyQualifiedName('.')); |
| } |
| } |
| |
| private IType chooseClassToTestType() { |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| if (root == null) |
| return null; |
| |
| IJavaElement[] elements= new IJavaElement[] { root.getJavaProject() }; |
| IJavaSearchScope scope= SearchEngine.createJavaSearchScope(elements); |
| |
| try { |
| SelectionDialog dialog= JavaUI.createTypeDialog(getShell(), getWizard().getContainer(), scope, IJavaElementSearchConstants.CONSIDER_CLASSES_AND_ENUMS, false, getClassUnderTestText()); |
| dialog.setTitle(WizardMessages.NewTestCaseWizardPageOne_class_to_test_dialog_title); |
| dialog.setMessage(WizardMessages.NewTestCaseWizardPageOne_class_to_test_dialog_message); |
| if (dialog.open() == Window.OK) { |
| Object[] resultArray= dialog.getResult(); |
| if (resultArray != null && resultArray.length > 0) |
| return (IType) resultArray[0]; |
| } |
| } catch (JavaModelException e) { |
| JUnitPlugin.log(e); |
| } |
| return null; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#packageChanged() |
| */ |
| protected IStatus packageChanged() { |
| IStatus status= super.packageChanged(); |
| fClassToTestCompletionProcessor.setPackageFragment(getPackageFragment()); |
| return status; |
| } |
| |
| /** |
| * Hook method that gets called when the class under test has changed. The method class under test |
| * returns the status of the validation. |
| * <p> |
| * Subclasses may extend this method to perform their own validation. |
| * </p> |
| * |
| * @return the status of the validation |
| */ |
| protected IStatus classUnderTestChanged() { |
| JUnitStatus status= new JUnitStatus(); |
| |
| |
| fClassUnderTest= null; |
| |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| if (root == null) { |
| return status; |
| } |
| |
| String classToTestName= getClassUnderTestText(); |
| if (classToTestName.length() == 0) { |
| return status; |
| } |
| IStatus val= JavaConventions.validateJavaTypeName(classToTestName); |
| if (val.getSeverity() == IStatus.ERROR) { |
| status.setError(WizardMessages.NewTestCaseWizardPageOne_error_class_to_test_not_valid); |
| return status; |
| } |
| |
| IPackageFragment pack= getPackageFragment(); // can be null |
| try { |
| IType type= resolveClassNameToType(root.getJavaProject(), pack, classToTestName); |
| if (type == null) { |
| status.setError(WizardMessages.NewTestCaseWizardPageOne_error_class_to_test_not_exist); |
| return status; |
| } |
| if (type.isInterface()) { |
| status.setWarning(Messages.format(WizardMessages.NewTestCaseWizardPageOne_warning_class_to_test_is_interface,classToTestName)); |
| } |
| |
| if (pack != null && !JUnitStubUtility.isVisible(type, pack)) { |
| status.setWarning(Messages.format(WizardMessages.NewTestCaseWizardPageOne_warning_class_to_test_not_visible, new String[] {(type.isInterface())?WizardMessages.NewTestCaseWizardPageOne_Interface:WizardMessages.NewTestCaseWizardPageOne_Class , classToTestName})); |
| } |
| fClassUnderTest= type; |
| fPage2.setClassUnderTest(fClassUnderTest); |
| } catch (JavaModelException e) { |
| status.setError(WizardMessages.NewTestCaseWizardPageOne_error_class_to_test_not_valid); |
| } |
| return status; |
| } |
| |
| /** |
| * Returns the content of the class to test text field. |
| * |
| * @return the name of the class to test |
| */ |
| public String getClassUnderTestText() { |
| return fClassUnderTestText; |
| } |
| |
| /** |
| * Returns the class to be tested. |
| * |
| * @return the class under test or <code>null</code> if the entered values are not valid |
| */ |
| public IType getClassUnderTest() { |
| return fClassUnderTest; |
| } |
| |
| /** |
| * Sets the name of the class under test. |
| * |
| * @param name The name to set |
| */ |
| public void setClassUnderTest(String name) { |
| if (fClassUnderTestControl != null && !fClassUnderTestControl.isDisposed()) { |
| fClassUnderTestControl.setText(name); |
| } |
| internalSetClassUnderText(name); |
| } |
| |
| private void internalSetClassUnderText(String name) { |
| fClassUnderTestText= name; |
| fClassUnderTestStatus= classUnderTestChanged(); |
| handleFieldChanged(CLASS_UNDER_TEST); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#createTypeMembers(org.eclipse.jdt.core.IType, org.eclipse.jdt.ui.wizards.NewTypeWizardPage.ImportsManager, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| protected void createTypeMembers(IType type, ImportsManager imports, IProgressMonitor monitor) throws CoreException { |
| if (fMethodStubsButtons.isSelected(0)) |
| createMain(type); |
| |
| if (fMethodStubsButtons.isSelected(4)) |
| createConstructor(type, imports); |
| |
| if (fMethodStubsButtons.isSelected(2)) { |
| createSetUp(type, imports); |
| } |
| |
| if (fMethodStubsButtons.isSelected(3)) { |
| createTearDown(type, imports); |
| } |
| |
| if (fClassUnderTest != null) { |
| createTestMethodStubs(type); |
| } |
| } |
| |
| private void createConstructor(IType type, ImportsManager imports) throws JavaModelException { |
| ITypeHierarchy typeHierarchy= null; |
| IType[] superTypes= null; |
| String content= ""; //$NON-NLS-1$ |
| IMethod methodTemplate= null; |
| if (type.exists()) { |
| typeHierarchy= type.newSupertypeHierarchy(null); |
| superTypes= typeHierarchy.getAllSuperclasses(type); |
| for (int i= 0; i < superTypes.length; i++) { |
| if (superTypes[i].exists()) { |
| IMethod constrMethod= superTypes[i].getMethod(superTypes[i].getElementName(), new String[] {"Ljava.lang.String;"}); //$NON-NLS-1$ |
| if (constrMethod.exists() && constrMethod.isConstructor()) { |
| methodTemplate= constrMethod; |
| break; |
| } |
| } |
| } |
| } |
| if (methodTemplate != null) { |
| GenStubSettings settings= JUnitStubUtility.getCodeGenerationSettings(type.getJavaProject()); |
| settings.fCallSuper= true; |
| settings.fMethodOverwrites= true; |
| content= JUnitStubUtility.genStub(getTypeName(), methodTemplate, settings, imports); |
| } else { |
| final String delimiter= getLineDelimiter(); |
| StringBuffer buffer= new StringBuffer(32); |
| buffer.append("public "); //$NON-NLS-1$ |
| buffer.append(getTypeName()); |
| buffer.append("("); //$NON-NLS-1$ |
| buffer.append(imports.addImport("java.lang.String")); //$NON-NLS-1$ |
| buffer.append(" name) {"); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append("super(name);"); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append("}"); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| content += buffer.toString(); |
| } |
| type.createMethod(content, null, true, null); |
| } |
| |
| private void createMain(IType type) throws JavaModelException { |
| type.createMethod(fMethodStubsButtons.getMainMethod(getTypeName()), null, false, null); |
| } |
| |
| private void createSetUp(IType type, ImportsManager imports) throws JavaModelException { |
| ITypeHierarchy typeHierarchy= null; |
| IType[] superTypes= null; |
| String content= ""; //$NON-NLS-1$ |
| IMethod methodTemplate= null; |
| if (type.exists()) { |
| typeHierarchy= type.newSupertypeHierarchy(null); |
| superTypes= typeHierarchy.getAllSuperclasses(type); |
| for (int i= 0; i < superTypes.length; i++) { |
| if (superTypes[i].exists()) { |
| IMethod testMethod= superTypes[i].getMethod(SETUP, new String[] {}); |
| if (testMethod.exists()) { |
| methodTemplate= testMethod; |
| break; |
| } |
| } |
| } |
| } |
| |
| GenStubSettings settings= JUnitStubUtility.getCodeGenerationSettings(type.getJavaProject()); |
| if (methodTemplate != null) { |
| settings.fCallSuper= true; |
| settings.fMethodOverwrites= true; |
| content= JUnitStubUtility.genStub(getTypeName(), methodTemplate, settings, imports); |
| } else { |
| final String delimiter= getLineDelimiter(); |
| StringBuffer buffer= new StringBuffer(); |
| if (settings.createComments) { |
| buffer.append("/**"); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append(" * Sets up the fixture, for example, open a network connection."); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append(" * This method is called before a test is executed."); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append(delimiter); |
| buffer.append(" * @throws "); //$NON-NLS-1$ |
| buffer.append(imports.addImport("java.lang.Exception")); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append(" */"); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| } |
| buffer.append("protected void "); //$NON-NLS-1$ |
| buffer.append(SETUP); |
| buffer.append("() throws "); //$NON-NLS-1$ |
| buffer.append(imports.addImport("java.lang.Exception")); //$NON-NLS-1$ |
| buffer.append(" {}"); //$NON-NLS-1$ |
| buffer.append(delimiter); |
| } |
| type.createMethod(content, null, false, null); |
| } |
| |
| private void createTearDown(IType type, ImportsManager imports) throws JavaModelException { |
| ITypeHierarchy typeHierarchy= null; |
| IType[] superTypes= null; |
| String tearDown= ""; //$NON-NLS-1$ |
| IMethod methodTemplate= null; |
| if (type.exists()) { |
| typeHierarchy= type.newSupertypeHierarchy(null); |
| superTypes= typeHierarchy.getAllSuperclasses(type); |
| for (int i= 0; i < superTypes.length; i++) { |
| if (superTypes[i].exists()) { |
| IMethod testM= superTypes[i].getMethod(TEARDOWN, new String[] {}); |
| if (testM.exists()) { |
| methodTemplate= testM; |
| break; |
| } |
| } |
| } |
| } |
| if (methodTemplate != null) { |
| GenStubSettings settings= JUnitStubUtility.getCodeGenerationSettings(type.getJavaProject()); |
| settings.fCallSuper= true; |
| settings.fMethodOverwrites= true; |
| tearDown= JUnitStubUtility.genStub(getTypeName(), methodTemplate, settings, imports); |
| type.createMethod(tearDown, null, false, null); |
| } |
| } |
| |
| private void createTestMethodStubs(IType type) throws JavaModelException { |
| IMethod[] methods= fPage2.getCheckedMethods(); |
| if (methods.length == 0) |
| return; |
| /* find overloaded methods */ |
| IMethod[] allMethodsArray= fPage2.getAllMethods(); |
| List allMethods= new ArrayList(); |
| allMethods.addAll(Arrays.asList(allMethodsArray)); |
| List overloadedMethods= getOveloadedMethods(allMethods); |
| |
| /* used when for example both sum and Sum methods are present. Then |
| * sum -> testSum |
| * Sum -> testSum1 |
| */ |
| List names= new ArrayList(); |
| for (int i = 0; i < methods.length; i++) { |
| IMethod method= methods[i]; |
| String elementName= method.getElementName(); |
| StringBuffer name= new StringBuffer(PREFIX).append(Character.toUpperCase(elementName.charAt(0))).append(elementName.substring(1)); |
| StringBuffer buffer= new StringBuffer(); |
| |
| final boolean contains= overloadedMethods.contains(method); |
| if (contains) |
| appendParameterNamesToMethodName(name, method.getParameterTypes()); |
| |
| replaceIllegalCharacters(name); |
| /* Should I for examples have methods |
| * void foo(java.lang.StringBuffer sb) {} |
| * void foo(mypackage1.StringBuffer sb) {} |
| * void foo(mypackage2.StringBuffer sb) {} |
| * I will get in the test class: |
| * testFooStringBuffer() |
| * testFooStringBuffer1() |
| * testFooStringBuffer2() |
| */ |
| String result= name.toString(); |
| if (names.contains(result)) { |
| int suffix= 1; |
| while (names.contains(result + Integer.toString(suffix))) |
| suffix++; |
| name.append(Integer.toString(suffix)); |
| } |
| result= name.toString(); |
| names.add(result); |
| appendMethodComment(buffer, method); |
| buffer.append("public ");//$NON-NLS-1$ |
| if (fPage2.getCreateFinalMethodStubsButtonSelection()) |
| buffer.append("final "); //$NON-NLS-1$ |
| buffer.append("void ");//$NON-NLS-1$ |
| buffer.append(result); |
| buffer.append("()");//$NON-NLS-1$ |
| try { |
| appendTestMethodBody(buffer, result, method); |
| } catch (CoreException exception) { |
| throw new JavaModelException(exception); |
| } |
| type.createMethod(buffer.toString(), null, false, null); |
| } |
| } |
| |
| private void replaceIllegalCharacters(StringBuffer buffer) { |
| char character= 0; |
| for (int index= buffer.length() - 1; index >= 0; index--) { |
| character= buffer.charAt(index); |
| if (Character.isWhitespace(character)) |
| buffer.deleteCharAt(index); |
| else if (character == '<') |
| buffer.replace(index, index + 1, OF_TAG); |
| else if (character == '?') |
| buffer.replace(index, index + 1, QUESTION_MARK_TAG); |
| else if (!Character.isJavaIdentifierPart(character)) |
| buffer.deleteCharAt(index); |
| } |
| } |
| |
| private String getLineDelimiter() throws JavaModelException{ |
| IType classToTest= getClassUnderTest(); |
| |
| if (classToTest != null && classToTest.exists() && classToTest.getCompilationUnit() != null) |
| return classToTest.getCompilationUnit().findRecommendedLineSeparator(); |
| |
| return getPackageFragment().findRecommendedLineSeparator(); |
| } |
| |
| private void appendTestMethodBody(StringBuffer buffer, String name, IMethod method) throws CoreException { |
| final String delimiter= getLineDelimiter(); |
| buffer.append("{").append(delimiter); //$NON-NLS-1$ |
| if (fPage2.isCreateTasks()) { |
| final String content= CodeGeneration.getMethodBodyContent(method.getCompilationUnit(), CLASS_UNDER_TEST, name, false, "", delimiter); //$NON-NLS-1$ |
| if (content != null && content.length() > 0) |
| buffer.append(content); |
| } |
| buffer.append(delimiter).append("}").append(delimiter).append(delimiter); //$NON-NLS-1$ |
| } |
| |
| private void appendParameterNamesToMethodName(StringBuffer buffer, String[] parameters) { |
| for (int i= 0; i < parameters.length; i++) { |
| final StringBuffer buf= new StringBuffer(Signature.getSimpleName(Signature.toString(Signature.getElementType(parameters[i])))); |
| final char character= buf.charAt(0); |
| if (buf.length() > 0 && !Character.isUpperCase(character)) |
| buf.setCharAt(0, Character.toUpperCase(character)); |
| buffer.append(buf.toString()); |
| for (int j= 0, arrayCount= Signature.getArrayCount(parameters[i]); j < arrayCount; j++) { |
| buffer.append("Array"); //$NON-NLS-1$ |
| } |
| } |
| } |
| |
| private void appendMethodComment(StringBuffer buffer, IMethod method) throws JavaModelException { |
| final String delimiter= getLineDelimiter(); |
| final StringBuffer buf= new StringBuffer(16); |
| JavaElementLabels.getMethodLabel(method, JavaElementLabels.ALL_DEFAULT | JavaElementLabels.M_FULLY_QUALIFIED, buf); |
| buffer.append("/*");//$NON-NLS-1$ |
| buffer.append(delimiter); |
| buffer.append(" * ");//$NON-NLS-1$ |
| buffer.append(Messages.format(WizardMessages.NewTestCaseWizardPageOne_comment_class_to_test, buf.toString())); |
| buffer.append(delimiter); |
| buffer.append(" */");//$NON-NLS-1$ |
| buffer.append(delimiter); |
| } |
| |
| private List getOveloadedMethods(List allMethods) { |
| List overloadedMethods= new ArrayList(); |
| for (int i= 0; i < allMethods.size(); i++) { |
| IMethod current= (IMethod) allMethods.get(i); |
| String currentName= current.getElementName(); |
| boolean currentAdded= false; |
| for (ListIterator iter= allMethods.listIterator(i+1); iter.hasNext(); ) { |
| IMethod iterMethod= (IMethod) iter.next(); |
| if (iterMethod.getElementName().equals(currentName)) { |
| //method is overloaded |
| if (!currentAdded) { |
| overloadedMethods.add(current); |
| currentAdded= true; |
| } |
| overloadedMethods.add(iterMethod); |
| iter.remove(); |
| } |
| } |
| } |
| return overloadedMethods; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.dialogs.IDialogPage#setVisible(boolean) |
| */ |
| public void setVisible(boolean visible) { |
| super.setVisible(visible); |
| if (!visible) { |
| saveWidgetValues(); |
| } |
| |
| //if (visible) setFocus(); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#containerChanged() |
| */ |
| protected IStatus containerChanged() { |
| IStatus containerStatus= super.containerChanged(); |
| if (!containerStatus.matches(IStatus.ERROR)) { |
| IStatus projectStatus= validateIfJUnitProject(); |
| if (!projectStatus.isOK()) { |
| return projectStatus; |
| } |
| } |
| return containerStatus; |
| } |
| |
| |
| /** |
| * The method is called when the container has changed to validate if the project |
| * is suited for the JUnit test class. Clients can override to modify or remove that validation. |
| * |
| * @return the status of the validation |
| */ |
| protected IStatus validateIfJUnitProject() { |
| JUnitStatus status= new JUnitStatus(); |
| IPackageFragmentRoot root= getPackageFragmentRoot(); |
| if (root == null) |
| return status; |
| |
| IJavaProject jp= root.getJavaProject(); |
| |
| try { |
| if (jp.findType(JUnitPlugin.TEST_SUPERCLASS_NAME) != null) |
| return status; |
| } catch (JavaModelException e) { |
| } |
| if (MessageDialog.openQuestion(getShell(), WizardMessages.NewTestCaseWizardPageOne_not_on_buildpath_title, WizardMessages.NewTestCaseWizardPageOne_not_on_buildpath_message)) { |
| try { |
| JUnitAddLibraryProposal.addJUnitToBuildPath(getShell(), jp); |
| return status; |
| } catch(JavaModelException e) { |
| ErrorDialog.openError(getShell(), WizardMessages.NewTestCaseWizardPageOne_cannot_add_title, WizardMessages.NewTestCaseWizardPageOne_cannot_add_message, e.getStatus()); |
| } |
| } |
| status.setWarning(WizardMessages.NewTestCaseWizardPageOne_error_junitNotOnbuildpath); |
| return status; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jdt.ui.wizards.NewTypeWizardPage#superClassChanged() |
| */ |
| protected IStatus superClassChanged() { |
| // replaces the super class validation of of the normal type wizard |
| |
| String superClassName= getSuperClass(); |
| JUnitStatus status= new JUnitStatus(); |
| if (superClassName == null || superClassName.trim().equals("")) { //$NON-NLS-1$ |
| status.setError(WizardMessages.NewTestCaseWizardPageOne_error_superclass_empty); |
| return status; |
| } |
| if (getPackageFragmentRoot() != null) { |
| try { |
| IType type= resolveClassNameToType(getPackageFragmentRoot().getJavaProject(), getPackageFragment(), superClassName); |
| if (type == null) { |
| /* TODO: is this a warning or error? */ |
| status.setWarning(WizardMessages.NewTestCaseWizardPageOne_error_superclass_not_exist); |
| return status; |
| } |
| if (type.isInterface()) { |
| status.setError(WizardMessages.NewTestCaseWizardPageOne_error_superclass_is_interface); |
| return status; |
| } |
| if (!TestSearchEngine.isTestImplementor(type)) { // TODO: expensive! |
| status.setError(Messages.format(WizardMessages.NewTestCaseWizardPageOne_error_superclass_not_implementing_test_interface, JUnitPlugin.TEST_INTERFACE_NAME)); |
| return status; |
| } |
| } catch (JavaModelException e) { |
| JUnitPlugin.log(e); |
| } |
| } |
| return status; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.jface.wizard.IWizardPage#canFlipToNextPage() |
| */ |
| public boolean canFlipToNextPage() { |
| return super.canFlipToNextPage() && getClassUnderTest() != null; |
| } |
| |
| private IType resolveClassNameToType(IJavaProject jproject, IPackageFragment pack, String classToTestName) throws JavaModelException { |
| |
| IType type= jproject.findType(classToTestName); |
| |
| // search in current package |
| if (type == null && pack != null && !pack.isDefaultPackage()) { |
| type= jproject.findType(pack.getElementName(), classToTestName); |
| } |
| |
| // search in java.lang |
| if (type == null) { |
| type= jproject.findType("java.lang", classToTestName); //$NON-NLS-1$ |
| } |
| return type; |
| } |
| |
| /** |
| * 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() { |
| IDialogSettings settings= getDialogSettings(); |
| if (settings != null) { |
| boolean generateMain= settings.getBoolean(STORE_GENERATE_MAIN); |
| fMethodStubsButtons.setSelection(0, generateMain); |
| fMethodStubsButtons.setEnabled(1, generateMain); |
| fMethodStubsButtons.setSelection(1,settings.getBoolean(STORE_USE_TESTRUNNER)); |
| try { |
| fMethodStubsButtons.setComboSelection(settings.getInt(STORE_TESTRUNNER_TYPE)); |
| } catch(NumberFormatException e) {} |
| } |
| } |
| |
| /** |
| * 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() { |
| IDialogSettings settings= getDialogSettings(); |
| if (settings != null) { |
| settings.put(STORE_GENERATE_MAIN, fMethodStubsButtons.isSelected(0)); |
| settings.put(STORE_USE_TESTRUNNER, fMethodStubsButtons.isSelected(1)); |
| settings.put(STORE_TESTRUNNER_TYPE, fMethodStubsButtons.getComboSelection()); |
| } |
| } |
| |
| } |