blob: 548f59b86e57b54ff9d93b9d57a6335d8ef166c1 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2013 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute and Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.ui.tests.refactoring;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import junit.framework.TestCase;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.ISourceManipulation;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.ITypeNameRequestor;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.internal.corext.refactoring.util.JavaElementUtil;
import org.eclipse.jdt.internal.corext.util.Strings;
import org.eclipse.ltk.core.refactoring.Change;
import org.eclipse.ltk.core.refactoring.CheckConditionsOperation;
import org.eclipse.ltk.core.refactoring.CreateChangeOperation;
import org.eclipse.ltk.core.refactoring.IUndoManager;
import org.eclipse.ltk.core.refactoring.PerformChangeOperation;
import org.eclipse.ltk.core.refactoring.Refactoring;
import org.eclipse.ltk.core.refactoring.RefactoringCore;
import org.eclipse.ltk.core.refactoring.RefactoringDescriptor;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.objectteams.otdt.core.IOTJavaElement;
import org.eclipse.objectteams.otdt.internal.core.AbstractCalloutMapping;
@SuppressWarnings("restriction")
public abstract class RefactoringTest extends TestCase
{
private IPackageFragmentRoot _root;
private IPackageFragment _packageP;
public boolean _isVerbose = false;
public static final String TEST_PATH_PREFIX = "";
protected static final String TEST_INPUT_INFIX = "/in/";
protected static final String TEST_OUTPUT_INFIX = "/out/";
protected static final String CONTAINER = "src";
public RefactoringTest(String name)
{
super(name);
}
protected void setUp() throws Exception
{
_root = MySetup.getDefaultSourceFolder();
_packageP = MySetup.getPackageP();
if (_isVerbose)
{
System.out
.println("\n---------------------------------------------");
System.out.println("\nTest:" + getClass() + "." + getName());
}
RefactoringCore.getUndoManager().flush();
}
protected void tearDown() throws Exception
{
refreshFromLocal();
performDummySearch();
if (getPackageP().exists())
{
tryDeletingAllJavaChildren(getPackageP());
tryDeletingAllNonJavaChildResources(getPackageP());
}
if (getRoot().exists())
{
IJavaElement[] packages = getRoot().getChildren();
for (int i = 0; i < packages.length; i++)
{
try
{
IPackageFragment pack = (IPackageFragment)packages[i];
if (!pack.equals(getPackageP()) && pack.exists()
&& !pack.isReadOnly())
pack.delete(true, null);
}
catch (JavaModelException ex)
{
//try to delete'em all
ex.printStackTrace();
}
}
}
}
private void refreshFromLocal() throws CoreException
{
if (getRoot().exists())
{
getRoot().getResource().
refreshLocal(IResource.DEPTH_INFINITE, null);
}
else if (getPackageP().exists())//don't refresh package if root already refreshed
{
getPackageP().getResource().
refreshLocal(IResource.DEPTH_INFINITE, null);
}
}
private static void tryDeletingAllNonJavaChildResources(
IPackageFragment pack) throws JavaModelException
{
Object[] nonJavaKids = pack.getNonJavaResources();
for (int i = 0; i < nonJavaKids.length; i++)
{
if (nonJavaKids[i] instanceof IResource)
{
IResource resource = (IResource)nonJavaKids[i];
try
{
resource.delete(true, null);
}
catch (CoreException ex)
{
//try to delete'em all
ex.printStackTrace();
}
}
}
}
private static void tryDeletingAllJavaChildren(IPackageFragment pack)
throws JavaModelException
{
IJavaElement[] kids = pack.getChildren();
for (int i = 0; i < kids.length; i++)
{
if (kids[i] instanceof ISourceManipulation)
{
try
{
if (kids[i].exists() && !kids[i].isReadOnly())
((ISourceManipulation)kids[i]).delete(true, null);
}
catch (JavaModelException ex)
{
//try to delete'em all
ex.printStackTrace();
}
}
}
}
protected IPackageFragmentRoot getRoot()
{
return _root;
}
protected IPackageFragment getPackageP()
{
return _packageP;
}
protected final Refactoring createRefactoring(RefactoringDescriptor descriptor) throws CoreException {
RefactoringStatus status= new RefactoringStatus();
Refactoring refactoring= descriptor.createRefactoring(status);
assertNotNull("refactoring should not be null", refactoring);
assertTrue("status should be ok", status.isOK());
return refactoring;
}
protected final RefactoringStatus performRefactoring(RefactoringDescriptor descriptor) throws Exception {
return performRefactoring(descriptor, true);
}
protected final RefactoringStatus performRefactoring(RefactoringDescriptor descriptor, boolean providesUndo) throws Exception {
Refactoring refactoring= createRefactoring(descriptor);
return performRefactoring(refactoring, providesUndo);
}
protected final RefactoringStatus performRefactoring(Refactoring ref)
throws Exception
{
return performRefactoring(ref, true);
}
protected final RefactoringStatus performRefactoring(Refactoring ref,
boolean providesUndo) throws Exception
{
performDummySearch();
IUndoManager undoManager = getUndoManager();
CreateChangeOperation create = new CreateChangeOperation(
new CheckConditionsOperation(ref,
CheckConditionsOperation.ALL_CONDITIONS),
RefactoringStatus.FATAL);
PerformChangeOperation perform = new PerformChangeOperation(create);
perform.setUndoManager(undoManager, ref.getName());
ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
RefactoringStatus status = create.getConditionCheckingStatus();
if (!status.isOK())
{
return status;
}
assertTrue("Change wasn't executed", perform.changeExecuted());
Change undo = perform.getUndoChange();
if (providesUndo)
{
assertNotNull("Undo doesn't exist", undo);
assertTrue("Undo manager is empty", undoManager.anythingToUndo());
}
else
{
assertNull("Undo manager contains undo but shouldn't", undo);
}
return null;
}
protected final RefactoringStatus performRefactoringWithStatus(
Refactoring ref) throws Exception
{
performDummySearch();
CreateChangeOperation create = new CreateChangeOperation(
new CheckConditionsOperation(ref,
CheckConditionsOperation.ALL_CONDITIONS),
RefactoringStatus.FATAL);
PerformChangeOperation perform = new PerformChangeOperation(create);
perform.setUndoManager(RefactoringCore.getUndoManager(), ref.getName());
ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
RefactoringStatus status = create.getConditionCheckingStatus();
if (status.hasFatalError())
{
return status;
}
assertTrue("Change wasn't executed", perform.changeExecuted());
return status;
}
protected void performDummySearch() throws Exception
{
performDummySearch(getPackageP());
}
protected final Change performChange(final Refactoring refactoring,
boolean storeUndo) throws Exception
{
CreateChangeOperation create = new CreateChangeOperation(refactoring);
PerformChangeOperation perform = new PerformChangeOperation(create);
if (storeUndo)
{
perform.setUndoManager(getUndoManager(), refactoring.getName());
}
ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
assertTrue("Change wasn't executed", perform.changeExecuted());
return perform.getUndoChange();
}
protected final Change performChange(final Change change) throws Exception
{
PerformChangeOperation perform = new PerformChangeOperation(change);
ResourcesPlugin.getWorkspace().run(perform, new NullProgressMonitor());
assertTrue("Change wasn't executed", perform.changeExecuted());
return perform.getUndoChange();
}
protected IUndoManager getUndoManager()
{
IUndoManager undoManager = RefactoringCore.getUndoManager();
undoManager.flush();
return undoManager;
}
/** ************** helpers ***************** */
/** ** mostly not general, just shortcuts **** */
protected IType getType(ICompilationUnit cu, String name)
throws JavaModelException
{
IType[] types = cu.getAllTypes();
for (int i = 0; i < types.length; i++)
{
if (types[i].getFullyQualifiedName().equals(name)
|| types[i].getElementName().equals(name))
{
return types[i];
}
}
return null;
}
/**
* subclasses override to inform about the location of their test cases
*/
protected String getRefactoringPath()
{
return "";
}
/**
* example "RenameType/"
*/
protected String getTestPath()
{
return TEST_PATH_PREFIX + getRefactoringPath();
}
/**
* @param cuName
* @param infix
* example "RenameTest/test0 + infix + cuName.java"
*/
protected String createTestFileName(String cuName, String infix)
{
return getTestPath() + getName() + infix + cuName + ".java";
}
protected String getInputTestFileName(String cuName)
{
return createTestFileName(cuName, TEST_INPUT_INFIX);
}
/**
* @param subDirName
* example "p/" or "org/eclipse/jdt/"
*/
protected String getInputTestFileName(String cuName, String subDirName)
{
return createTestFileName(cuName, TEST_INPUT_INFIX + subDirName);
}
protected String getOutputTestFileName(String cuName)
{
return createTestFileName(cuName, TEST_OUTPUT_INFIX);
}
/**
* @param subDirName
* example "p/" or "org/eclipse/jdt/"
*/
protected String getOutputTestFileName(String cuName, String subDirName)
{
return createTestFileName(cuName, TEST_OUTPUT_INFIX + subDirName);
}
protected ICompilationUnit createCUfromTestFile(IPackageFragment pack,
String cuName) throws Exception
{
return createCUfromTestFile(pack, cuName, true);
}
protected ICompilationUnit createCUfromTestFile(IPackageFragment pack,
String cuName, String subDirName) throws Exception
{
return createCUfromTestFile(pack, cuName, subDirName, true);
}
protected ICompilationUnit createCUfromTestFile(IPackageFragment pack,
String cuName, boolean input) throws Exception
{
String contents = input ? getFileContents(getInputTestFileName(cuName))
: getFileContents(getOutputTestFileName(cuName));
return createCU(pack, cuName + ".java", contents);
}
protected ICompilationUnit createCUfromTestFile(IPackageFragment pack,
String cuName, String subDirName, boolean input) throws Exception
{
String contents = input ? getFileContents(getInputTestFileName(cuName,
subDirName)) : getFileContents(getOutputTestFileName(cuName,
subDirName));
return createCU(pack, cuName + ".java", contents);
}
protected void printTestDisabledMessage(String explanation)
{
System.out.println("\n" + getClass().getName() + "::" + getName()
+ " disabled (" + explanation + ")");
}
protected ICompilationUnit[] createCUs(String[] cuNames) throws Exception {
ICompilationUnit[] cus = new ICompilationUnit[cuNames.length];
for (int idx = 0; idx < cuNames.length; idx++) {
Assert.isNotNull(cuNames[idx]);
cus[idx] = createCUfromTestFile(getPackageP(), cuNames[idx]);
}
return cus;
}
protected String createInputTestFileName(ICompilationUnit[] cus, int idx) {
return getInputTestFileName(getSimpleNameOfCu(cus[idx].getElementName()));
}
protected String createOutputTestFileName(ICompilationUnit[] cus, int idx) {
return getOutputTestFileName(getSimpleNameOfCu(cus[idx].getElementName()));
}
private String getSimpleNameOfCu(String compUnit) {
int dot = compUnit.lastIndexOf('.');
return compUnit.substring(0, dot);
}
//-----------------------
public static InputStream getStream(String content)
{
return new StringBufferInputStream(content);
}
public static IPackageFragmentRoot getSourceFolder(
IJavaProject javaProject, String name) throws JavaModelException
{
IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
for (int i = 0; i < roots.length; i++)
{
if (!roots[i].isArchive() && roots[i].getElementName().equals(name))
return roots[i];
}
return null;
}
public static String getFileContents(String fileName) throws IOException
{
return getContents(getFileInputStream(fileName));
}
public static String getContents(IFile file) throws IOException,
CoreException
{
return getContents(file.getContents());
}
public static ICompilationUnit createCU(IPackageFragment pack, String name,
String contents) throws Exception
{
if (pack.getCompilationUnit(name).exists())
{
return pack.getCompilationUnit(name);
}
ICompilationUnit cu = pack.createCompilationUnit(name, contents, true,
null);
cu.save(null, true);
return cu;
}
public static String getContents(InputStream in) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(in));
StringBuffer sb = new StringBuffer(300);
try
{
int read = 0;
while ((read = br.read()) != -1)
{
sb.append((char)read);
}
}
finally
{
br.close();
}
return sb.toString();
}
public static InputStream getFileInputStream(String fileName)
throws IOException
{
return OTRefactoringTestPlugin.getDefault().getTestResourceStream(
fileName);
}
public static String removeExtension(String fileName)
{
return fileName.substring(0, fileName.lastIndexOf('.'));
}
public static void performDummySearch(IJavaElement element)
throws Exception
{
new SearchEngine().searchAllTypeNames(ResourcesPlugin.getWorkspace(),
null, null, SearchPattern.R_EXACT_MATCH, true,
IJavaSearchConstants.CLASS, SearchEngine
.createJavaSearchScope(new IJavaElement[] { element }),
new Requestor(),
IJavaSearchConstants.WAIT_UNTIL_READY_TO_SEARCH, null);
}
public static IMember[] merge(IMember[] a1, IMember[] a2, IMember[] a3)
{
return JavaElementUtil.merge(JavaElementUtil.merge(a1, a2), a3);
}
public static IMember[] merge(IMember[] a1, IMember[] a2)
{
return JavaElementUtil.merge(a1, a2);
}
public static IField[] getFields(IType type, String[] names)
throws JavaModelException
{
if (names == null)
{
return new IField[0];
}
Set<IField> fields = new HashSet<IField>();
for (int i = 0; i < names.length; i++)
{
IField field = type.getField(names[i]);
assertTrue("field " + field.getElementName() + " does not exist",
field.exists());
fields.add(field);
}
return fields.toArray(new IField[fields.size()]);
}
public static IType[] getMemberTypes(IType type, String[] names)
throws JavaModelException
{
if (names == null)
{
return new IType[0];
}
Set<IType> memberTypes = new HashSet<IType>();
for (int i = 0; i < names.length; i++)
{
IType memberType = type.getType(names[i]);
assertTrue("member type " + memberType.getElementName()
+ " does not exist", memberType.exists());
memberTypes.add(memberType);
}
return memberTypes.toArray(new IType[memberTypes.size()]);
}
public static IMethod[] getMethods(IType type, String[] names,
String[][] signatures) throws JavaModelException
{
return getMethods(type, names, signatures, null, false);
}
public static IMethod[] getMethods(IType type, String[] names, String[][] signatures,
boolean[] flags, boolean flag)
throws JavaModelException
{
if (names == null || signatures == null)
{
return new IMethod[0];
}
List<IMethod> methods = new ArrayList<IMethod>(names.length);
for (int i = 0; i < names.length; i++)
{
// use flags to filter sub-set of names/signatures:
if (flags != null && flags[i] != flag) continue;
IMethod method = type.getMethod(names[i], signatures[i]);
if (!method.exists()) {
// search a callout mapping that might be "equal" to this method:
for (IJavaElement child : type.getChildren()) {
int elementType = child.getElementType();
if (elementType == IOTJavaElement.CALLOUT_MAPPING || elementType == IOTJavaElement.CALLOUT_TO_FIELD_MAPPING) {
AbstractCalloutMapping map = (AbstractCalloutMapping) child;
if (method.equals(map.getCorrespondingJavaElement())) {
method = map;
break;
}
}
}
}
assertTrue("method " + method.getElementName() + " does not exist",
method.exists());
if (!methods.contains(method))
{
methods.add(method);
}
}
return methods.toArray(new IMethod[methods.size()]);
}
public static IType[] findTypes(IType[] types, String[] namesOfTypesToPullUp)
{
List<IType> found = new ArrayList<IType>(types.length);
for (int i = 0; i < types.length; i++)
{
IType type = types[i];
for (int j = 0; j < namesOfTypesToPullUp.length; j++)
{
String name = namesOfTypesToPullUp[j];
if (type.getElementName().equals(name))
{
found.add(type);
}
}
}
return found.toArray(new IType[found.size()]);
}
public static IField[] findFields(IField[] fields,
String[] namesOfFieldsToPullUp)
{
List<IField> found = new ArrayList<IField>(fields.length);
for (int i = 0; i < fields.length; i++)
{
IField field = fields[i];
for (int j = 0; j < namesOfFieldsToPullUp.length; j++)
{
String name = namesOfFieldsToPullUp[j];
if (field.getElementName().equals(name))
{
found.add(field);
}
}
}
return found.toArray(new IField[found.size()]);
}
public static IMethod[] findMethods(IMethod[] selectedMethods,
String[] namesOfMethods, String[][] signaturesOfMethods)
{
List<IMethod> found = new ArrayList<IMethod>(selectedMethods.length);
for (int i = 0; i < selectedMethods.length; i++)
{
IMethod method = selectedMethods[i];
String[] paramTypes = method.getParameterTypes();
for (int j = 0; j < namesOfMethods.length; j++)
{
String methodName = namesOfMethods[j];
if (!methodName.equals(method.getElementName()))
{
continue;
}
String[] methodSig = signaturesOfMethods[j];
if (!areSameSignatures(paramTypes, methodSig))
{
continue;
}
found.add(method);
}
}
return found.toArray(new IMethod[found.size()]);
}
private static boolean areSameSignatures(String[] s1, String[] s2)
{
if (s1.length != s2.length)
{
return false;
}
for (int i = 0; i < s1.length; i++)
{
if (!s1[i].equals(s2[i]))
{
return false;
}
}
return true;
}
/**
* Line-based version of junit.framework.Assert.assertEquals(String, String)
* without considering line delimiters.
*/
public static void assertEqualLines(String expected, String actual)
{
assertEqualLines("", expected, actual);
}
/**
* Line-based version of junit.framework.Assert.assertEquals(String, String, String)
* without considering line delimiters.
*/
public static void assertEqualLines(String message, String expected,
String actual)
{
String[] expectedLines = Strings.convertIntoLines(expected);
String[] actualLines = Strings.convertIntoLines(actual);
String expected2 = (expectedLines == null ? null : Strings.concatenate(
expectedLines, "\n"));
String actual2 = (actualLines == null ? null : Strings.concatenate(
actualLines, "\n"));
assertEquals(message, expected2, actual2);
}
private static class Requestor implements ITypeNameRequestor
{
public void acceptClass(char[] packageName, char[] simpleTypeName,
char[][] enclosingTypeNames, String path)
{
}
public void acceptInterface(char[] packageName, char[] simpleTypeName,
char[][] enclosingTypeNames, String path)
{
}
}
}