|
Lines 11-124
Link Here
|
| 11 |
**********************************************************************/ |
11 |
**********************************************************************/ |
| 12 |
package org.eclipse.hyades.test.tools.core.internal.java.codegen; |
12 |
package org.eclipse.hyades.test.tools.core.internal.java.codegen; |
| 13 |
|
13 |
|
| 14 |
import java.io.ByteArrayInputStream; |
|
|
| 15 |
import java.util.ArrayList; |
14 |
import java.util.ArrayList; |
| 16 |
import java.util.Arrays; |
15 |
import java.util.Collection; |
| 17 |
import java.util.Iterator; |
16 |
import java.util.Iterator; |
| 18 |
import java.util.List; |
17 |
import java.util.List; |
| 19 |
|
18 |
|
| 20 |
import org.eclipse.core.resources.IFile; |
19 |
import org.eclipse.core.resources.IProject; |
|
|
20 |
import org.eclipse.core.runtime.CoreException; |
| 21 |
import org.eclipse.core.runtime.IProgressMonitor; |
21 |
import org.eclipse.core.runtime.IProgressMonitor; |
| 22 |
import org.eclipse.core.runtime.NullProgressMonitor; |
|
|
| 23 |
import org.eclipse.core.runtime.SubProgressMonitor; |
22 |
import org.eclipse.core.runtime.SubProgressMonitor; |
| 24 |
import org.eclipse.emf.ecore.EObject; |
|
|
| 25 |
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase; |
23 |
import org.eclipse.hyades.models.common.facades.behavioral.ITestCase; |
| 26 |
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; |
24 |
import org.eclipse.hyades.models.common.facades.behavioral.ITestSuite; |
| 27 |
import org.eclipse.hyades.test.core.util.EMFUtil; |
|
|
| 28 |
import org.eclipse.hyades.test.tools.core.CorePlugin; |
25 |
import org.eclipse.hyades.test.tools.core.CorePlugin; |
|
|
26 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.ASTHelper; |
| 29 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper; |
27 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.Helper; |
| 30 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.IProjectDependencyUpdater; |
28 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.IProjectDependencyUpdater; |
| 31 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.ImportManager; |
29 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.ImportManager; |
| 32 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.JavaGenerator; |
30 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.JavaGenerator; |
| 33 |
import org.eclipse.hyades.test.tools.core.internal.java.modelsync.JUnitModelUpdater; |
31 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.changes.AssociateModelSourceChange; |
| 34 |
import org.eclipse.hyades.test.tools.core.internal.java.modelsync.JUnitProjectBuilder; |
32 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.changes.CompilationUnitChange; |
|
|
33 |
import org.eclipse.hyades.test.tools.core.internal.common.codegen.changes.PotentialChange; |
| 34 |
import org.eclipse.hyades.test.tools.core.internal.java.JavaMessages; |
| 35 |
import org.eclipse.jdt.core.ICompilationUnit; |
35 |
import org.eclipse.jdt.core.ICompilationUnit; |
| 36 |
import org.eclipse.jdt.core.IMethod; |
36 |
import org.eclipse.jdt.core.IMethod; |
| 37 |
import org.eclipse.jdt.core.IType; |
|
|
| 38 |
import org.eclipse.jdt.core.JavaCore; |
37 |
import org.eclipse.jdt.core.JavaCore; |
| 39 |
import org.eclipse.jdt.core.JavaModelException; |
38 |
import org.eclipse.jdt.core.JavaModelException; |
|
|
39 |
import org.eclipse.jdt.core.dom.AST; |
| 40 |
import org.eclipse.jdt.core.dom.ASTParser; |
| 41 |
import org.eclipse.jdt.core.dom.CompilationUnit; |
| 42 |
import org.eclipse.jdt.core.dom.Javadoc; |
| 43 |
import org.eclipse.jdt.core.dom.MethodDeclaration; |
| 44 |
import org.eclipse.jdt.core.dom.Name; |
| 45 |
import org.eclipse.jdt.core.dom.SimpleType; |
| 46 |
import org.eclipse.jdt.core.dom.SingleVariableDeclaration; |
| 47 |
import org.eclipse.jdt.core.dom.TagElement; |
| 48 |
import org.eclipse.jdt.core.dom.Type; |
| 49 |
import org.eclipse.jdt.core.dom.TypeDeclaration; |
| 50 |
import org.eclipse.jface.text.Document; |
| 51 |
import org.eclipse.ltk.core.refactoring.Change; |
| 52 |
import org.eclipse.ltk.core.refactoring.NullChange; |
| 53 |
import org.eclipse.text.edits.MalformedTreeException; |
| 54 |
import org.eclipse.text.edits.TextEdit; |
| 40 |
|
55 |
|
| 41 |
/** |
56 |
/** |
|
|
57 |
* JUnit code generator. |
| 58 |
* This concrete implementation handles code generation and code update for JUnit and |
| 59 |
* JUnit Plugin types. |
| 42 |
* @author marcelop, jcanches |
60 |
* @author marcelop, jcanches |
| 43 |
* @since 1.0.2 |
61 |
* @since 1.0.2 |
| 44 |
*/ |
62 |
*/ |
| 45 |
public class JUnitGenerator extends JavaGenerator { |
63 |
public class JUnitGenerator extends JavaGenerator { |
| 46 |
|
64 |
|
| 47 |
private String superclassName; |
65 |
private String superclassName; |
|
|
66 |
private boolean destructiveChangeFound; |
| 48 |
|
67 |
|
| 49 |
public JUnitGenerator(IProjectDependencyUpdater updater) { |
68 |
public JUnitGenerator(ITestSuite testSuite, IProjectDependencyUpdater updater) { |
| 50 |
super(updater); |
69 |
super(testSuite, new JUnitProjectDependencyUpdater(updater, !testSuite.getImplementor().isExternalImplementor())); |
| 51 |
} |
70 |
} |
| 52 |
|
71 |
|
| 53 |
public JUnitGenerator(IProjectDependencyUpdater updater, String superclassName) { |
72 |
public JUnitGenerator(ITestSuite testSuite, IProjectDependencyUpdater updater, String superclassName) { |
| 54 |
this(updater); |
73 |
this(testSuite, updater); |
| 55 |
this.superclassName = superclassName; |
74 |
this.superclassName = superclassName; |
| 56 |
} |
75 |
} |
| 57 |
|
76 |
|
| 58 |
/** |
77 |
/** |
| 59 |
* @see org.eclipse.hyades.test.common.internal.codegen.Generator#generateFile(org.eclipse.hyades.models.common.facades.behavioral.ITestSuite, org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor) |
78 |
* @see org.eclipse.hyades.test.common.internal.codegen.Generator#generateFile(org.eclipse.hyades.models.common.facades.behavioral.ITestSuite, org.eclipse.core.resources.IFile, org.eclipse.core.runtime.IProgressMonitor) |
| 60 |
*/ |
79 |
*/ |
| 61 |
protected void generateFile(ITestSuite testSuite, IFile file, IProgressMonitor monitor) |
80 |
protected String generateCode(IProgressMonitor monitor) throws CoreException { |
| 62 |
throws Exception |
|
|
| 63 |
{ |
| 64 |
Helper helper = new Helper(); |
81 |
Helper helper = new Helper(); |
| 65 |
if (this.superclassName != null) { |
82 |
try { |
| 66 |
helper.setSuperclassName(this.superclassName); |
83 |
if (this.superclassName != null) { |
|
|
84 |
helper.setSuperclassName(this.superclassName); |
| 85 |
} |
| 86 |
ITestSuite testSuite = getTestSuite(); |
| 87 |
computeTestMethodNames(testSuite, testSuite.getImplementor().isExternalImplementor(), helper); |
| 88 |
GenTestSuite generator = new GenTestSuite(); |
| 89 |
return Helper.formatContent(generator.generate(testSuite, helper)); |
| 90 |
} finally { |
| 91 |
helper.dispose(); |
| 67 |
} |
92 |
} |
| 68 |
computeTestMethodNames(testSuite, testSuite.getImplementor().isExternalImplementor(), helper); |
|
|
| 69 |
GenTestSuite generator = new GenTestSuite(); |
| 70 |
String content = Helper.formatContent(generator.generate(testSuite, helper)); |
| 71 |
// use UTF-8 encoding - bugzilla_88029 running test with non-ASCII characters. |
| 72 |
file.create(new ByteArrayInputStream(content.getBytes(CHARSET_UTF8)), true, monitor); |
| 73 |
file.setCharset(CHARSET_UTF8, monitor); |
| 74 |
helper.dispose(); |
| 75 |
// Associate the java file to the testsuite file |
| 76 |
associateJavaFileToTestSuite(file, testSuite); |
| 77 |
} |
93 |
} |
| 78 |
|
94 |
|
| 79 |
protected void updateFile(ITestSuite testSuite, IFile file, IProgressMonitor monitor) { |
95 |
protected Change createPostCodegenerationChange(IProgressMonitor monitor) throws CoreException { |
|
|
96 |
PotentialChange change = new AssociateModelSourceChange(getFileHandle(), getTestSuite()); |
| 97 |
if (change.isRequired()) { |
| 98 |
return change; |
| 99 |
} |
| 100 |
return new NullChange(); |
| 101 |
} |
| 102 |
|
| 103 |
protected Change createSourceUpdateChange(SubProgressMonitor monitor) throws CoreException { |
| 80 |
monitor.beginTask("", 4); //$NON-NLS-1$ |
104 |
monitor.beginTask("", 4); //$NON-NLS-1$ |
| 81 |
try { |
105 |
try { |
| 82 |
ICompilationUnit cu = JavaCore.createCompilationUnitFrom(file); |
106 |
ASTParser parser = ASTParser.newParser(AST.JLS3); // TODO Compute the argument |
|
|
107 |
ITestSuite testSuite = getTestSuite(); |
| 108 |
ICompilationUnit compilationUnit = JavaCore.createCompilationUnitFrom(getFileHandle()); |
| 109 |
|
| 83 |
Helper helper = new Helper(); |
110 |
Helper helper = new Helper(); |
| 84 |
String packageName = helper.getPackageName(testSuite); |
111 |
String packageName = helper.getPackageName(testSuite); |
| 85 |
helper.setImportManager(new ImportManager(packageName)); |
112 |
helper.setImportManager(new ImportManager(packageName)); |
| 86 |
try { |
113 |
try { |
| 87 |
if (cu == null || !cu.isStructureKnown()) { |
114 |
// Parse the source code |
| 88 |
// TODO ask the user whether to override the code or not modify it |
115 |
destructiveChangeFound = false; |
| 89 |
return; |
116 |
Document doc = new Document(compilationUnit.getBuffer().getContents()); |
| 90 |
} |
117 |
parser.setSource(doc.get().toCharArray()); |
| 91 |
IType mainClass = cu.findPrimaryType(); |
118 |
CompilationUnit cu = (CompilationUnit) parser.createAST(new SubProgressMonitor(monitor, 1)); |
| 92 |
cu.becomeWorkingCopy(null, new SubProgressMonitor(monitor, 1)); |
119 |
cu.recordModifications(); |
| 93 |
try { |
120 |
TypeDeclaration mainType = ASTHelper.getMainType(cu); |
| 94 |
updateTestMethods(testSuite, mainClass, helper, |
121 |
if (mainType == null) { |
| 95 |
new SubProgressMonitor(monitor, 1)); |
122 |
// TODO Error |
| 96 |
// The generation of suite() must be performed after the test methods update |
123 |
return new NullChange(); |
| 97 |
// because the methods names might change during the update. |
124 |
} |
| 98 |
if (!testSuite.getImplementor().isExternalImplementor()) { |
125 |
|
| 99 |
updateSuiteMethod(testSuite, mainClass, helper); |
126 |
// Modify the AST tree |
| 100 |
checkConstructor(mainClass, helper); |
127 |
updateTestMethods(testSuite, mainType, helper, new SubProgressMonitor(monitor, 1)); |
| 101 |
} |
128 |
// The generation of suite() must be performed after the test methods update |
| 102 |
monitor.worked(1); |
129 |
// because the methods names might change during the update. |
| 103 |
helper.emitSortedImports(cu); |
130 |
if (!testSuite.getImplementor().isExternalImplementor()) { |
| 104 |
|
131 |
updateSuiteMethod(testSuite, mainType, helper); |
| 105 |
cu.commitWorkingCopy(/*force*/false, |
132 |
checkConstructor(mainType, helper); |
| 106 |
new SubProgressMonitor(monitor, 1)); |
133 |
checkSuperType(mainType, helper); |
| 107 |
// Associate the java file to the testsuite file |
134 |
} |
| 108 |
associateJavaFileToTestSuite(file, testSuite); |
135 |
monitor.worked(1); |
| 109 |
} finally { |
136 |
// Emit to AST the imports that are newly required by the updated code |
| 110 |
cu.discardWorkingCopy(); |
137 |
helper.emitSortedImports(cu); |
|
|
138 |
|
| 139 |
// Compute the resulting document and save it |
| 140 |
TextEdit edit = cu.rewrite(doc, /*options*/null); |
| 141 |
if (edit.getChildrenSize() != 0) { |
| 142 |
CompilationUnitChange change = new CompilationUnitChange(JavaMessages.UPDATE_JUNIT_CODE, compilationUnit, destructiveChangeFound); |
| 143 |
change.setEdit(edit); |
| 144 |
return change; |
| 111 |
} |
145 |
} |
| 112 |
} catch (JavaModelException e) { |
146 |
} catch (JavaModelException e) { |
| 113 |
CorePlugin.logError(e); |
147 |
CorePlugin.logError(e); |
|
|
148 |
} catch (MalformedTreeException e) { |
| 149 |
CorePlugin.logError(e); |
| 114 |
} finally { |
150 |
} finally { |
| 115 |
helper.dispose(); |
151 |
helper.dispose(); |
| 116 |
} |
152 |
} |
| 117 |
} finally { |
153 |
} finally { |
| 118 |
monitor.done(); |
154 |
monitor.done(); |
| 119 |
} |
155 |
} |
|
|
156 |
return new NullChange(); |
| 120 |
} |
157 |
} |
| 121 |
|
158 |
|
|
|
159 |
protected void checkSuperType(TypeDeclaration mainType, Helper helper) { |
| 160 |
boolean doIt = false; |
| 161 |
Type superclassType = mainType.getSuperclassType(); |
| 162 |
if (superclassType == null) { |
| 163 |
doIt = true; |
| 164 |
} |
| 165 |
|
| 166 |
if (superclassType.isSimpleType()) { |
| 167 |
SimpleType st = (SimpleType)superclassType; |
| 168 |
Name supertypeName = ASTHelper.resolveName((CompilationUnit)mainType.getParent(), st.getName()); |
| 169 |
if (supertypeName != null && !Helper.HYADES_TEST_CASE_CLASS_NAME.equals(supertypeName.getFullyQualifiedName())) { |
| 170 |
doIt = true; |
| 171 |
} |
| 172 |
} |
| 173 |
if (doIt) { |
| 174 |
destructiveChangeFound = true; |
| 175 |
helper.addImport(Helper.HYADES_TEST_CASE_CLASS_NAME); |
| 176 |
Name newName = mainType.getAST().newName(helper.getImportedName(Helper.HYADES_TEST_CASE_CLASS_NAME)); |
| 177 |
if (superclassType == null) { |
| 178 |
superclassType = mainType.getAST().newSimpleType(newName); |
| 179 |
mainType.setSuperclassType(superclassType); |
| 180 |
} else { |
| 181 |
((SimpleType)superclassType).setName(newName); |
| 182 |
} |
| 183 |
} |
| 184 |
} |
| 185 |
|
| 122 |
/** |
186 |
/** |
| 123 |
* Update the content of the suite() method for the specified class, |
187 |
* Update the content of the suite() method for the specified class, |
| 124 |
* with the behavior of the specified test suite. |
188 |
* with the behavior of the specified test suite. |
|
Lines 126-152
Link Here
|
| 126 |
* the method if it does not exist. |
190 |
* the method if it does not exist. |
| 127 |
* @throws JavaModelException |
191 |
* @throws JavaModelException |
| 128 |
*/ |
192 |
*/ |
| 129 |
protected void updateSuiteMethod(ITestSuite testSuite, IType mainClass, Helper helper) throws JavaModelException { |
193 |
protected void updateSuiteMethod(ITestSuite testSuite, TypeDeclaration mainType, Helper helper) throws JavaModelException { |
| 130 |
// Compute the suite() method body |
194 |
// Compute the suite() method body |
| 131 |
GenSuiteMethod generator = new GenSuiteMethod(); |
195 |
GenSuiteMethod generator = new GenSuiteMethod(); |
| 132 |
String content = generator.generate(testSuite, helper); |
196 |
String content = generator.generate(testSuite, helper); |
| 133 |
IMethod suiteMethod = mainClass.getMethod("suite", new String[0]); //$NON-NLS-1$ |
197 |
MethodDeclaration newSuiteMethod = ASTHelper.parseMethod(mainType.getAST(), content); |
| 134 |
IMethod sibling = null; // The suite() method sits before this method |
198 |
|
| 135 |
if (suiteMethod.exists()) { |
199 |
// Compute the existing suite() method index and removes it if it exists |
| 136 |
IMethod[] methods = mainClass.getMethods(); |
200 |
MethodDeclaration suiteMethod = ASTHelper.findMethodWithNoParameter(mainType, "suite"); //$NON-NLS-1$ |
| 137 |
int index = Arrays.asList(methods).indexOf(suiteMethod); |
201 |
int index; |
| 138 |
suiteMethod.delete(/*force*/false, new NullProgressMonitor()); |
202 |
if (suiteMethod == null) { |
| 139 |
methods = mainClass.getMethods(); |
203 |
index = ASTHelper.getFirstMethodIndex(mainType); |
| 140 |
if (index < methods.length) { |
|
|
| 141 |
sibling = methods[index]; |
| 142 |
} |
| 143 |
} else { |
204 |
} else { |
| 144 |
IMethod[] methods = mainClass.getMethods(); |
205 |
destructiveChangeFound = true; |
| 145 |
if (methods.length > 0) { |
206 |
index = mainType.bodyDeclarations().indexOf(suiteMethod); |
| 146 |
sibling = methods[0]; |
207 |
mainType.bodyDeclarations().remove(index); |
| 147 |
} |
208 |
} |
|
|
209 |
|
| 210 |
// Inserts the new MethodDeclaration at the right position |
| 211 |
if (index == -1) { |
| 212 |
mainType.bodyDeclarations().add(newSuiteMethod); |
| 213 |
} else { |
| 214 |
mainType.bodyDeclarations().add(index, newSuiteMethod); |
| 148 |
} |
215 |
} |
| 149 |
mainClass.createMethod(Helper.formatContent(content, 0), sibling, /*force*/true, new NullProgressMonitor()); |
|
|
| 150 |
} |
216 |
} |
| 151 |
|
217 |
|
| 152 |
/** |
218 |
/** |
|
Lines 156-168
Link Here
|
| 156 |
* @param helper |
222 |
* @param helper |
| 157 |
* @throws JavaModelException |
223 |
* @throws JavaModelException |
| 158 |
*/ |
224 |
*/ |
| 159 |
protected void checkConstructor(IType mainClass, Helper helper) throws JavaModelException { |
225 |
protected void checkConstructor(TypeDeclaration mainType, Helper helper) throws JavaModelException { |
| 160 |
IMethod method = mainClass.getMethod(mainClass.getElementName(), new String[] { "QString;" }); //$NON-NLS-1$ |
226 |
MethodDeclaration pattern = mainType.getAST().newMethodDeclaration(); |
| 161 |
if (method.exists()) return; |
227 |
pattern.setName(mainType.getAST().newSimpleName(mainType.getName().getIdentifier())); |
| 162 |
GenTestSuiteConstructor generator = new GenTestSuiteConstructor(); |
228 |
SingleVariableDeclaration svd = mainType.getAST().newSingleVariableDeclaration(); |
| 163 |
String contents = generator.generate(mainClass.getElementName(), helper); |
229 |
svd.setType(mainType.getAST().newSimpleType(mainType.getAST().newSimpleName("String"))); //$NON-NLS-1$ |
| 164 |
IMethod[] methods = mainClass.getMethods(); |
230 |
pattern.parameters().add(svd); |
| 165 |
mainClass.createMethod(Helper.formatContent(contents, 0), methods.length == 0 ? null : methods[0], /*force*/true, new NullProgressMonitor()); |
231 |
|
|
|
232 |
MethodDeclaration constructor = ASTHelper.findMethod(mainType, pattern); |
| 233 |
if (constructor == null) { |
| 234 |
GenTestSuiteConstructor generator = new GenTestSuiteConstructor(); |
| 235 |
String contents = generator.generate(mainType.getName().getIdentifier(), helper); |
| 236 |
constructor = ASTHelper.parseMethod(mainType.getAST(), contents); |
| 237 |
int index = ASTHelper.getFirstMethodIndex(mainType); |
| 238 |
if (index == -1) { |
| 239 |
mainType.bodyDeclarations().add(constructor); |
| 240 |
} else { |
| 241 |
mainType.bodyDeclarations().add(index, constructor); |
| 242 |
} |
| 243 |
} |
| 244 |
} |
| 245 |
|
| 246 |
/** |
| 247 |
* Returns whether a method is a test method. |
| 248 |
* @param method |
| 249 |
* @return |
| 250 |
*/ |
| 251 |
public static boolean isTestMethod(MethodDeclaration method) { |
| 252 |
String name = method.getName().getIdentifier(); |
| 253 |
return name.startsWith("test") && method.parameters().size() == 0; //$NON-NLS-1$ |
| 166 |
} |
254 |
} |
| 167 |
|
255 |
|
| 168 |
/** |
256 |
/** |
|
Lines 175-181
Link Here
|
| 175 |
String[] types = method.getParameterTypes(); |
263 |
String[] types = method.getParameterTypes(); |
| 176 |
return name.startsWith("test") && types.length == 0; //$NON-NLS-1$ |
264 |
return name.startsWith("test") && types.length == 0; //$NON-NLS-1$ |
| 177 |
} |
265 |
} |
| 178 |
|
266 |
|
| 179 |
/** |
267 |
/** |
| 180 |
* Update the list of test methods in the specified class, so that the list of |
268 |
* Update the list of test methods in the specified class, so that the list of |
| 181 |
* test methods matches the list of test cases of the specified test suite. |
269 |
* test methods matches the list of test cases of the specified test suite. |
|
Lines 184-191
Link Here
|
| 184 |
* @param helper |
272 |
* @param helper |
| 185 |
* @throws JavaModelException |
273 |
* @throws JavaModelException |
| 186 |
*/ |
274 |
*/ |
| 187 |
protected void updateTestMethods(ITestSuite testSuite, IType mainClass, Helper helper, IProgressMonitor monitor) throws JavaModelException { |
275 |
protected void updateTestMethods(ITestSuite testSuite, TypeDeclaration mainType, Helper helper, IProgressMonitor monitor) throws JavaModelException { |
| 188 |
IMethod[] methods = mainClass.getMethods(); |
276 |
MethodDeclaration[] methods = mainType.getMethods(); |
| 189 |
monitor.beginTask("", methods.length + testSuite.getITestCases().size()); //$NON-NLS-1$ |
277 |
monitor.beginTask("", methods.length + testSuite.getITestCases().size()); //$NON-NLS-1$ |
| 190 |
try { |
278 |
try { |
| 191 |
List usedTestMethods = new ArrayList(methods.length); |
279 |
List usedTestMethods = new ArrayList(methods.length); |
|
Lines 200-222
Link Here
|
| 200 |
actualMethodName = computedMethodName; |
288 |
actualMethodName = computedMethodName; |
| 201 |
Helper.setTestMethodName(testCase, actualMethodName); |
289 |
Helper.setTestMethodName(testCase, actualMethodName); |
| 202 |
} |
290 |
} |
| 203 |
IMethod method = mainClass.getMethod(actualMethodName, new String[0]); |
291 |
MethodDeclaration method = ASTHelper.findMethodWithNoParameter(mainType, actualMethodName); |
| 204 |
if (!method.exists()) { |
292 |
if (method == null) { |
| 205 |
method = createTestMethod(mainClass, testCase, helper); |
293 |
method = createTestMethod(mainType, testCase, helper); |
| 206 |
} else { |
294 |
} else { |
| 207 |
// We still need to rename the method to conform to the computed name |
295 |
updateTestMethod(testCase, computedMethodName, method, helper); |
| 208 |
if (!computedMethodName.equals(actualMethodName)) { |
|
|
| 209 |
method.rename(computedMethodName, /*replace*/true, new SubProgressMonitor(monitor, 1)); |
| 210 |
Helper.setTestMethodName(testCase, computedMethodName); |
| 211 |
} |
| 212 |
} |
296 |
} |
| 213 |
usedTestMethods.add(method); |
297 |
usedTestMethods.add(method); |
| 214 |
monitor.worked(1); |
298 |
monitor.worked(1); |
| 215 |
} |
299 |
} |
| 216 |
// 2) Remove unused test methods |
300 |
// 2) Remove unused test methods |
| 217 |
for (int i = 0; i< methods.length; i++) { |
301 |
for (int i = 0; i < methods.length; i++) { |
| 218 |
if (isTestMethod(methods[i]) && !usedTestMethods.contains(methods[i])) { |
302 |
if (isTestMethod(methods[i]) && !usedTestMethods.contains(methods[i])) { |
| 219 |
methods[i].delete(/*force*/false, new NullProgressMonitor()); |
303 |
destructiveChangeFound = true; |
|
|
304 |
mainType.bodyDeclarations().remove(methods[i]); |
| 220 |
} |
305 |
} |
| 221 |
monitor.worked(1); |
306 |
monitor.worked(1); |
| 222 |
} |
307 |
} |
|
Lines 224-263
Link Here
|
| 224 |
monitor.done(); |
309 |
monitor.done(); |
| 225 |
} |
310 |
} |
| 226 |
} |
311 |
} |
|
|
312 |
|
| 313 |
protected void updateTestMethod(ITestCase testCase, String newName, MethodDeclaration method, Helper helper) { |
| 314 |
// Update method name if necessary |
| 315 |
if (!newName.equals(method.getName().getIdentifier())) { |
| 316 |
destructiveChangeFound = true; |
| 317 |
method.setName(method.getAST().newSimpleName(newName)); |
| 318 |
Helper.setTestMethodName(testCase, newName); |
| 319 |
} |
| 320 |
// Update comments if necessary |
| 321 |
Javadoc javadoc = method.getJavadoc(); |
| 322 |
if (javadoc == null) { |
| 323 |
javadoc = method.getAST().newJavadoc(); |
| 324 |
method.setJavadoc(javadoc); |
| 325 |
} |
| 326 |
updateDescriptionTag(javadoc, testCase); |
| 327 |
} |
| 328 |
|
| 329 |
protected void updateDescriptionTag(Javadoc javadoc, ITestCase testCase) { |
| 330 |
TagElement oldtag = null; |
| 331 |
if (!javadoc.tags().isEmpty()) { |
| 332 |
TagElement tag = (TagElement) javadoc.tags().get(0); |
| 333 |
if (tag.getTagName() == null) { |
| 334 |
oldtag = tag; |
| 335 |
} |
| 336 |
} |
| 337 |
|
| 338 |
if (oldtag != null) { |
| 339 |
String sourceDescription = ASTHelper.extractDescription(oldtag); |
| 340 |
String modelDescription = makeJavadocDescription(testCase); |
| 341 |
if (!Helper.compareJavaComments(sourceDescription, modelDescription)) { |
| 342 |
destructiveChangeFound = true; |
| 343 |
javadoc.tags().remove(oldtag); |
| 344 |
ASTHelper.addDescriptionToJavadoc(javadoc, modelDescription); |
| 345 |
} |
| 346 |
} else { |
| 347 |
ASTHelper.addDescriptionToJavadoc(javadoc, makeJavadocDescription(testCase)); |
| 348 |
} |
| 349 |
} |
| 350 |
|
| 351 |
public static String makeJavadocDescription(ITestCase testCase) { |
| 352 |
StringBuffer buf = new StringBuffer(); |
| 353 |
buf.append(testCase.getName()); |
| 354 |
if (testCase.getDescription() != null) { |
| 355 |
String descr = testCase.getDescription().trim(); |
| 356 |
if (descr.length() > 0) { |
| 357 |
buf.append("\r\n"); //$NON-NLS-1$ |
| 358 |
buf.append(descr); |
| 359 |
} |
| 360 |
} |
| 361 |
return buf.toString(); |
| 362 |
} |
| 227 |
|
363 |
|
| 228 |
/** |
364 |
/** |
| 229 |
* Creates a test method for the specified test case. |
365 |
* Creates a test method for the specified test case. |
| 230 |
* @param mainClass |
|
|
| 231 |
* @param testCase |
| 232 |
* @param helper |
| 233 |
* @throws JavaModelException |
| 234 |
*/ |
366 |
*/ |
| 235 |
protected IMethod createTestMethod(IType mainClass, ITestCase testCase, Helper helper) throws JavaModelException { |
367 |
protected MethodDeclaration createTestMethod(TypeDeclaration mainType, ITestCase testCase, Helper helper) throws JavaModelException { |
| 236 |
GenTestMethod generator = new GenTestMethod(); |
368 |
GenTestMethod generator = new GenTestMethod(); |
| 237 |
String content = generator.generate(testCase, helper); |
369 |
String content = generator.generate(testCase, helper); |
| 238 |
return mainClass.createMethod(content, null, /*force*/false, new NullProgressMonitor()); |
370 |
MethodDeclaration method = ASTHelper.parseMethod(mainType.getAST(), content); |
|
|
371 |
mainType.bodyDeclarations().add(method); |
| 372 |
return method; |
| 239 |
} |
373 |
} |
| 240 |
|
374 |
|
| 241 |
private void associateJavaFileToTestSuite(IFile javaFile, ITestSuite testSuite) { |
375 |
public static class JUnitProjectDependencyUpdater implements IProjectDependencyUpdater { |
| 242 |
try { |
376 |
|
| 243 |
if (testSuite instanceof EObject) { |
377 |
private IProjectDependencyUpdater delegate; |
| 244 |
EObject eObject = (EObject) testSuite; |
378 |
|
| 245 |
IFile testSuiteFile = EMFUtil.getWorkspaceFile(eObject); |
379 |
public JUnitProjectDependencyUpdater(IProjectDependencyUpdater delegate, boolean modelBehavioring) { |
| 246 |
if (testSuiteFile != null && testSuiteFile.exists()) { |
380 |
this.delegate = delegate; |
| 247 |
// Add the Junit builder to the file's project (if not already installed) |
381 |
delegate.addRequiredPlugin("org.junit", "junit.jar"); //$NON-NLS-1$ //$NON-NLS-2$ |
| 248 |
JUnitProjectBuilder.installBuilder(javaFile.getProject()); |
382 |
if (modelBehavioring) { |
| 249 |
// Also add the JUnit builder to the test suite's project (the source file |
383 |
delegate.addRequiredPlugin(CorePlugin.getID(), "common.runner.jar"); //$NON-NLS-1$ |
| 250 |
// and the test suite usually are under the same project, but this is not |
384 |
delegate.addRequiredPlugin(CorePlugin.getID(), "java.runner.jar"); //$NON-NLS-1$ |
| 251 |
// mandatory). |
|
|
| 252 |
JUnitProjectBuilder.installBuilder(testSuiteFile.getProject()); |
| 253 |
// Record the link from the java file to the testsuite file |
| 254 |
JUnitModelUpdater.associateTestSuiteToJUnitSourceFile( |
| 255 |
javaFile, testSuiteFile); |
| 256 |
} |
| 257 |
} |
385 |
} |
| 258 |
} catch (Throwable t) { |
|
|
| 259 |
CorePlugin.logError(t); |
| 260 |
} |
386 |
} |
|
|
387 |
|
| 388 |
public void addRequiredPlugin(String pluginId, String jarName) { |
| 389 |
delegate.addRequiredPlugin(pluginId, jarName); |
| 390 |
} |
| 391 |
|
| 392 |
public void addRequiredProject(IProject project) { |
| 393 |
delegate.addRequiredProject(project); |
| 394 |
} |
| 395 |
|
| 396 |
public void adjustProject(IProject project, IProgressMonitor monitor) throws CoreException { |
| 397 |
delegate.adjustProject(project, monitor); |
| 398 |
} |
| 399 |
|
| 400 |
public Collection previewAdjustProject(IProject project) { |
| 401 |
return delegate.previewAdjustProject(project); |
| 402 |
} |
| 403 |
|
| 261 |
} |
404 |
} |
| 262 |
|
405 |
|
| 263 |
} |
406 |
} |