blob: 5bfa4f066b85df92e7a5ef0596d4ac393a8ea21b [file] [log] [blame]
/*******************************************************************************
* 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
*******************************************************************************/
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.internal.corext.codemanipulation.StubUtility;
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.ui.util.SWTUtil;
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 = SWTUtil.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, 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(){
IType classToTest= getClassUnderTest();
if (classToTest != null && classToTest.exists())
return StubUtility.getLineDelimiterUsed(classToTest);
return StubUtility.getLineDelimiterUsed(getPackageFragment());
}
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= StubUtility.getMethodBodyContent(false, method.getJavaProject(), CLASS_UNDER_TEST, name, "", 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());
}
}
}