/******************************************************************************* * Copyright (c) 2000, 2011 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 *******************************************************************************/ package org.eclipse.jdt.core.tests.model; import junit.framework.Test; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.*; import org.eclipse.jdt.core.*; public class RenameTests extends CopyMoveTests { ICompilationUnit cu; /** */ public RenameTests(String name) { super(name); } /** * Attempts to rename the elements with optional * forcing. The operation should fail with the failure code. */ public void renameNegative(IJavaElement[] elements ,String[] renamings, boolean force, int failureCode) { try { //rename getJavaModel().rename(elements, new IJavaElement[]{elements[0].getParent()}, renamings, force, null); } catch (JavaModelException jme) { assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode); return; } assertTrue("The rename should have failed for multiple renaming", false); return; } /** * Attempts to rename the element with optional * forcing. The operation should fail with the failure code. */ public void renameNegative(IJavaElement element, String rename, boolean force, int failureCode) { try { //rename getJavaModel().rename(new IJavaElement[] {element}, new IJavaElement[] {element.getParent()}, new String[] {rename}, force, null); } catch (JavaModelException jme) { assertTrue("Code not correct for JavaModelException: " + jme, jme.getStatus().getCode() == failureCode); return; } assertTrue("The rename should have failed for: " + element, false); return; } /** * Renames the element to the container with optional * forcing. The operation should succeed, so any exceptions * encountered are thrown. */ public void renamePositive(IJavaElement[] elements, String[] names, boolean force) throws JavaModelException { renamePositive(elements, new IJavaElement[]{elements[0].getParent()}, names, force); } /** * Renames the element to the container with optional * forcing. The operation should succeed, so any exceptions * encountered are thrown. */ public void renamePositive(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean force) throws JavaModelException { renamePositive(elements, destinations, names, force, false); } /** * Renames the element to the container with optional * forcing. The operation should succeed, so any exceptions * encountered are thrown. */ public void renamePositive(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean force, boolean originalShouldExist) throws JavaModelException { renamePositive(elements, destinations, names, force, originalShouldExist, null); } /** * Renames the element to the container with optional * forcing. The operation should succeed, so any exceptions * encountered are thrown. */ public void renamePositive(IJavaElement[] elements, IJavaElement[] destinations, String[] names, boolean force, boolean originalShouldExist, IProgressMonitor monitor) throws JavaModelException { // if forcing, ensure that a name collision exists int i; if (force) { for (i = 0; i < elements.length; i++) { IJavaElement e = elements[i]; IJavaElement collision = generateHandle(e, names[i], e.getParent()); assertTrue("Collision does not exist", collision.exists()); } } // rename getJavaModel().rename(elements, destinations, names, force, monitor); for (i = 0; i < elements.length; i++) { // generate the new element handle IJavaElement e = elements[i]; IJavaElement renamed = generateHandle(e, names[i], e.getParent()); assertTrue("Renamed element should exist", renamed.exists()); if (!originalShouldExist) { assertTrue("Original element should not exist", !e.exists()); } IJavaElementDelta destDelta = this.deltaListener.getDeltaFor(renamed.getParent()); if (isMainType(e, e.getParent())) { assertTrue("Renamed compilation unit as result of main type not added", destDelta != null && destDelta.getKind() == IJavaElementDelta.ADDED); assertTrue("Added children not correct for element copy", destDelta.getElement().equals(renamed.getParent())); assertTrue("flag should be F_MOVED_FROM", (destDelta.getFlags() & IJavaElementDelta.F_MOVED_FROM) > 0); assertTrue("moved from handle should be original", destDelta.getMovedFromElement().equals(e.getParent())); } else { assertTrue("Destination container not changed", destDelta != null && deltaChildrenChanged(destDelta)); IJavaElementDelta[] deltas = force ? destDelta.getChangedChildren() : destDelta.getAddedChildren(); assertTrue("Added children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(renamed)); assertTrue("kind should be K_ADDED", deltas[i].getKind() == (force? IJavaElementDelta.CHANGED : IJavaElementDelta.ADDED)); deltas = destDelta.getRemovedChildren(); assertTrue("Removed children not correct for element rename", deltas.length > i && deltas[i].getElement().equals(e)); assertTrue("kind should be K_REMOVED", deltas[i].getKind() == IJavaElementDelta.REMOVED); } } } /** * Renames the element to the container with optional * forcing. The operation should succeed, so any exceptions * encountered are thrown. */ public void renamePositive(IJavaElement element, String rename, boolean force) throws JavaModelException { renamePositive(new IJavaElement[] {element}, new String[] {rename}, force); } /** * Setup for the next test. */ public void setUp() throws Exception { super.setUp(); this.createJavaProject("P", new String[] {"src"}, "bin"); this.createFile( "/P/src/X.java", "public class X {\n" + " boolean other;\n" + " int bar;\n" + " {\n" + " bar = 1;\n" + " }\n" + " X(int i) {\n" + " }\n" + " void otherMethod(String s) {\n" + " }\n" + " void foo(String s) {\n" + " }\n" + "}" ); this.cu = getCompilationUnit("/P/src/X.java"); startDeltas(); } public void setUpSuite() throws Exception { super.setUpSuite(); IJavaProject project = this.createJavaProject("BinaryProject", new String[] {"src"}, new String[] {"JCL_LIB"}, "lib"); this.createFile( "/BinaryProject/src/X.java", "public class X {\n" + " int bar;\n" + " public void foo() {\n" + " }\n" + "}" ); project.getProject().build(IncrementalProjectBuilder.FULL_BUILD, null); waitForAutoBuild(); project.setRawClasspath( new IClasspathEntry[] { JavaCore.newLibraryEntry(new Path("/BinaryProject/lib"), null, null) }, null ); } // Use this static initializer to specify subset for tests // All specified tests which do not belong to the class are skipped... static { // Names of tests to run: can be "testBugXXXX" or "BugXXXX") // TESTS_PREFIX = "testCombineAccessRestrictions"; // TESTS_NAMES = new String[] {"testRenameFieldFragment"}; // TESTS_NUMBERS = new int[] { 5, 6 }; // TESTS_RANGE = new int[] { 21, 38 }; } public static Test suite() { return buildModelTestSuite(RenameTests.class); } /** * Cleanup after the previous test. */ public void tearDown() throws Exception { stopDeltas(); this.deleteProject("P"); super.tearDown(); } public void tearDownSuite() throws Exception { this.deleteProject("BinaryProject"); super.tearDownSuite(); } /** * Ensures that a binary field cannot be renamed. */ public void testRenameBinaryField() throws JavaModelException { IClassFile cf = getClassFile("BinaryProject", "lib", "", "X.class"); IField binaryField = cf.getType().getField("bar"); renameNegative(binaryField, "fred", false, IJavaModelStatusConstants.READ_ONLY); } /** * Ensures that a binary method cannot be renamed. */ public void testRenameBinaryMethod() throws JavaModelException { IClassFile cf = getClassFile("BinaryProject", "lib", "", "X.class"); IMethod binaryMethod = cf.getType().getMethods()[0]; renameNegative(binaryMethod, "fred", false, IJavaModelStatusConstants.READ_ONLY); } /** * Ensures that a binary type cannot be renamed. */ public void testRenameBinaryType() throws JavaModelException { IClassFile cf = getClassFile("BinaryProject", "lib", "", "X.class"); IType binaryType = cf.getType(); renameNegative(binaryType, "Y", false, IJavaModelStatusConstants.READ_ONLY); } /** * This operation should fail as renaming a CU and a CU member at the * same time is not supported. */ public void testRenameCompilationUnitAndType() { renameNegative( new IJavaElement[] {this.cu, this.cu.getType("X")}, new String[]{"Y.java", "Y"}, false, IJavaModelStatusConstants.INVALID_ELEMENT_TYPES); } /** * Ensures that compilation units cannot be renamed to an existing cu name * unless the force flag is set. */ public void testRenameCompilationUnitResultingInCollision() throws CoreException{ this.createFile( "/P/src/Y.java", "public class Y {\n" + "}" ); renameNegative(this.cu, "Y.java", false, IJavaModelStatusConstants.NAME_COLLISION); renamePositive(this.cu, "Y.java", true); } /** * Ensures that compilation units can be renamed. * Verifies that the proper change deltas are generated as a side effect * of running the operation. */ public void testRenameCompilationUnitsCheckingDeltas() throws CoreException{ this.createFile( "/P/src/Y.java", "public class Y {\n" + "}" ); ICompilationUnit cu2 = this.getCompilationUnit("/P/src/Y.java"); clearDeltas(); renamePositive( new ICompilationUnit[] {this.cu, cu2}, new String[] {"NewX.java", "NewY.java"}, false); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " NewX.java[+]: {MOVED_FROM(X.java [in <default> [in src [in P]]])}\n" + " NewY.java[+]: {MOVED_FROM(Y.java [in <default> [in src [in P]]])}\n" + " X.java[-]: {MOVED_TO(NewX.java [in <default> [in src [in P]]])}\n" + " Y.java[-]: {MOVED_TO(NewY.java [in <default> [in src [in P]]])}" ); } /** * Ensures that a compilation unit cannot be renamed to an invalid name. * The new name for a cu must end in .java and be a valid Java identifier. */ public void testRenameCompilationUnitWithInvalidName() { renameNegative(this.cu, "NewX", false, IJavaModelStatusConstants.INVALID_NAME); renameNegative(this.cu, "New X.java", false, IJavaModelStatusConstants.INVALID_NAME); } /** * This operation should fail as renaming a CU with a null name should throw * an <code>IllegalArgumentException</code> */ public void testRenameCompilationUnitWithNull() throws JavaModelException { try { this.cu.rename(null, false, null); } catch (IllegalArgumentException iae) { return; } assertTrue("Should not be able to rename a cu with a null name", false); } /** * Ensures that a construtor cannot be renamed using the * <code>RenameElementsOperation</code>. */ public void testRenameConstructor() { IMethod constructor = this.cu.getType("X").getMethod("X", new String[] {"I"}); renameNegative(constructor, "newName", false, IJavaModelStatusConstants.NAME_COLLISION); } /** * */ public void testRenameCU1() throws CoreException { this.cu.rename("NewX.java", false, null); assertTrue("Original CU should not exist", !this.cu.exists()); ICompilationUnit newCU = getCompilationUnit("/P/src/NewX.java"); assertTrue("New CU should exist", newCU.exists()); assertTypesEqual( "Unexpected types", "NewX\n", newCU.getAllTypes()); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " NewX.java[+]: {MOVED_FROM(X.java [in <default> [in src [in P]]])}\n" + " X.java[-]: {MOVED_TO(NewX.java [in <default> [in src [in P]]])}" ); } public void testRenameCU2() throws CoreException { this.createFile( "/P/src/Y.java", "public class Y {\n" + "}" ); clearDeltas(); this.cu.rename("Y.java", true, null); IFile file = (IFile)this.cu.getResource(); ICompilationUnit destCU = getCompilationUnit("/P/src/Y.java"); IFile destFile = (IFile)destCU.getResource(); assertTrue("Original CU should not exist", !this.cu.exists()); assertTrue("Original file should not exist", !file.exists()); assertTrue("Destination CU should exist", destCU.exists()); assertTrue("Destination file should exist", destFile.exists()); assertTypesEqual( "Unexpected types", "Y\n", destCU.getAllTypes()); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " X.java[-]: {MOVED_TO(Y.java [in <default> [in src [in P]]])}\n" + " Y.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" + " Y[+]: {MOVED_FROM(X [in X.java [in <default> [in src [in P]]]])}" ); } /* * Ensures that the correct scheduling rule is used when running ICompilationUnit.rename(...) * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=142990 ) */ public void testRenameCU3() throws Exception { IWorkspaceRunnable runnable = new IWorkspaceRunnable(){ public void run(IProgressMonitor monitor) throws CoreException { RenameTests.this.cu.rename("NewX.java", false, null); assertTrue("Original CU should not exist", !RenameTests.this.cu.exists()); } }; getWorkspace().run(runnable, getFolder("/P/src"), IResource.NONE, null); } /* * Ensures that the correct scheduling rule is used when running ICompilationUnit.rename(...) * (regression test for https://bugs.eclipse.org/bugs/show_bug.cgi?id=142990 ) */ public void testRenameCU4() throws Exception { createFolder("/P/src/p1"); createFile("/P/src/p1/X.java", "package p1; public class X {}"); IWorkspaceRunnable runnable = new IWorkspaceRunnable(){ public void run(IProgressMonitor monitor) throws CoreException { ICompilationUnit x = getCompilationUnit("/P/src/p1/X.java"); x.rename("NewX.java", false, null); assertTrue("Original CU should not exist", !x.exists()); } }; getWorkspace().run(runnable, getFolder("/P/src/p1"), IResource.NONE, null); } /* * Ensures that renaming an empty package fragment doesn't make it disappear * (regression test for bug 24505 Refactoring an empty package makes it disappears) */ public void testRenameEmptyPF() throws CoreException { this.createFolder("/P/src/x/y/z"); clearDeltas(); getPackage("/P/src/x/y/z").rename("x.y", false, null); IPackageFragment newFrag = getPackage("/P/src/x/y"); assertTrue("New package should exist", newFrag.exists()); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " x.y.z[-]: {MOVED_TO(x.y [in src [in P]])}\n" + " x.y[+]: {MOVED_FROM(x.y.z [in src [in P]])}" ); } /* * Ensures that renaming an enum also renames the constructors of this enum. * (regression test for bug 83593 Rename of enum type does not update constructor / throws ClassCastException) */ public void testRenameEnum() throws CoreException { try { createJavaProject("P15", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); createFile( "/P15/En.java", "public enum En {\n" + " ;\n" + " En() {\n" + " }\n" + "}" ); ICompilationUnit enumCU = getCompilationUnit("/P15/En.java"); enumCU.rename("OtherEnum.java", false, null); ICompilationUnit renamedCu = getCompilationUnit("/P15/OtherEnum.java"); assertSourceEquals( "Unexpected source after rename", "public enum OtherEnum {\n" + " ;\n" + " OtherEnum() {\n" + " }\n" + "}", renamedCu.getSource() ); } finally { deleteProject("P15"); } } /* * Ensures that renaming an enum that contain an enum constant with a body doesn't throw a ClassCastExeption. * (regression test for bug 83593 Rename of enum type does not update constructor / throws ClassCastException) */ public void testRenameEnum2() throws CoreException { try { createJavaProject("P15", new String[] {""}, new String[] {"JCL15_LIB"}, "", "1.5"); createFile( "/P15/En.java", "public enum En {\n" + " CONST() {\n" + " }\n" + "}" ); ICompilationUnit enumCU = getCompilationUnit("/P15/En.java"); enumCU.rename("OtherEnum.java", false, null); ICompilationUnit renamedCu = getCompilationUnit("/P15/OtherEnum.java"); assertSourceEquals( "Unexpected source after rename", "public enum OtherEnum {\n" + " CONST() {\n" + " }\n" + "}", renamedCu.getSource() ); } finally { deleteProject("P15"); } } /** * Ensures that fields can be renamed. * Verifies that the proper change deltas are generated as a side effect * of running the operation. As well ensures that the fields are * positioned in the same location as before the rename. */ public void testRenameFieldsCheckingDeltasAndPositions() throws JavaModelException { IType type = this.cu.getType("X"); IField field = type.getField("bar"); renamePositive(field, "fred", false); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " X.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" + " X[*]: {CHILDREN | FINE GRAINED}\n" + " bar[-]: {}\n" + " fred[+]: {}" ); ensureCorrectPositioning(type, type.getField("fred"), type.getField("other")); } /* * Ensures that renaming a field fragment renames the right fragment * (regression test for bug 121076 Wrong field gets renamed) */ public void testRenameFieldFragment() throws Exception { this.createFile( "/P/src/Y.java", "public class Y {\n" + " int int1, int2, int3;\n" + "}" ); ICompilationUnit c = getCompilationUnit("/P/src/Y.java"); IType type = c.getType("Y"); IField field = type.getField("int2"); renamePositive(field, "int2_renamed", false); } /** * Ensures that fields can be renamed even if one of the renamings fails. */ public void testRenameFieldsMultiStatus() throws CoreException { String addition = "multiStatus"; IType type = this.cu.getType("X"); IField[] iFields = type.getFields(); String[] newNames = new String[iFields.length]; int i; for (i = 0; i < iFields.length; i++) { IField f = iFields[i]; newNames[i] = addition + f.getElementName(); } newNames[1] = ";"; //invalid name boolean e = false; try { type.getJavaModel().rename(iFields, new IJavaElement[] {type}, newNames, false, null); } catch (JavaModelException jme) { assertTrue("Should not be multistatus (only one failure)", !jme.getStatus().isMultiStatus()); assertTrue("Should be an invalid destination", jme.getStatus().getCode() == IJavaModelStatusConstants.INVALID_NAME); e = true; } assertTrue("Should have been an exception", e); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " <default>[*]: {CHILDREN}\n" + " X.java[*]: {CHILDREN | FINE GRAINED | PRIMARY RESOURCE}\n" + " X[*]: {CHILDREN | FINE GRAINED}\n" + " multiStatusother[+]: {}\n" + " other[-]: {}" ); IJavaElement copy = generateHandle(iFields[0], newNames[0], type); assertTrue("Copy should exist", copy.exists()); } /** * Ensures that fields cannot be renamed to the same name. */ public void testRenameFieldsResultingInCollision() throws JavaModelException { String addition = "new"; IType type= this.cu.getType("X"); IField[] iFields = type.getFields(); String[] newNames = new String[iFields.length]; int i; for (i = 0; i < iFields.length; i++) { IField f = iFields[i]; newNames[i] = addition + f.getElementName(); } //set two fields to have the same new name newNames[i-1]= newNames[i-2]; renameNegative(iFields, newNames, false, IJavaModelStatusConstants.NAME_COLLISION); } /** * Ensures that renaming can be canceled. */ public void testRenameFieldsWithCancel() throws CoreException { boolean isCanceled = false; String addition = "new1"; IType type = RenameTests.this.cu.getType("X"); IField[] iFields = type.getFields(); String[] newNames = new String[iFields.length]; int i; for (i = 0; i < iFields.length; i++) { IField f = iFields[i]; newNames[i] = addition + f.getElementName(); } try { TestProgressMonitor monitor = TestProgressMonitor.getInstance(); monitor.setCancelledCounter(1); renamePositive(iFields, new IJavaElement[] {type}, newNames, false, false, monitor); } catch (OperationCanceledException e) { isCanceled = true; } assertTrue("Operation should have thrown an operation canceled exception", isCanceled); } /** * Ensures that an initializer cannot be renamed. */ public void testRenameInitializer() { IType typeSource= this.cu.getType("X"); IInitializer initializerSource= typeSource.getInitializer(1); renameNegative(initializerSource, "someName", false, IJavaModelStatusConstants.INVALID_ELEMENT_TYPES); } /** * Ensures that main types can be renamed. As a side effect * of renaming the main types, the types' enclosing compilation unit * are renamed as well. */ public void testRenameMainTypes() throws CoreException { this.createFile( "/P/src/Y.java", "public class Y {\n" + " public Y() {\n" + " }\n" + "}" ); ICompilationUnit cu2 = getCompilationUnit("/P/src/Y.java"); IPackageFragment pkg = (IPackageFragment) this.cu.getParent(); IJavaElement[] types = new IJavaElement[] { this.cu.getType("X"), cu2.getType("Y") }; String[] newNames = new String[] {"NewX", "NewY"}; renamePositive( new IJavaElement[] { this.cu.getType("X"), cu2.getType("Y") }, new IJavaElement[] { types[0].getParent(), types[1].getParent()}, newNames, false); //test that both the compilation unit, main type and constructors have been renamed. ICompilationUnit renamedCU1= pkg.getCompilationUnit("NewX.java"); ICompilationUnit renamedCU2= pkg.getCompilationUnit("NewY.java"); IType newType1 = renamedCU1.getType("NewX"); IType newType2 = renamedCU2.getType("NewY"); assertTrue("NewX should be present", newType1.exists()); assertTrue("NewY should be present", newType2.exists()); IMethod constructor1 = newType1.getMethod("NewX", new String[] {"I"}); IMethod constructor2 = newType2.getMethod("NewY", new String[] {}); assertTrue("NewX(int) should be present", constructor1.exists()); assertTrue("NewY() should be present", constructor2.exists()); } /** * Ensures that main types can be renamed as well as a child of a main type. As a side effect * of renaming the main types, the types enclosing compilation unit * are renamed as well. * @see "1FTKMBD: ITPJCORE:ALL - JM- Cannot rename parent and child with the same operation" */ public void testRenameMainTypesAndAChild() throws CoreException { this.createFile( "/P/src/Y.java", "public class Y {\n" + " public Y() {\n" + " }\n" + "}" ); ICompilationUnit cu2 = getCompilationUnit("/P/src/Y.java"); String[] newNames = new String[] { "newBar", "NewX", "NewY" }; IJavaElement[] elements = new IJavaElement[] { this.cu.getType("X").getField("bar"), this.cu.getType("X"), cu2.getType("Y") }; IJavaElement[] destinations = new IJavaElement[elements.length]; for (int i = 0; i < elements.length; i++) { destinations[i] = elements[i].getParent(); } getJavaModel().rename(elements, destinations, newNames, false, null); //test that both the compilation unit and the main type have been renamed. IPackageFragment pkg = (IPackageFragment) this.cu.getParent(); ICompilationUnit renamedCU1= pkg.getCompilationUnit("NewX.java"); IType newX = renamedCU1.getType("NewX"); assertTrue("NewX should be present", newX.exists()); ICompilationUnit renamedCU2= pkg.getCompilationUnit("NewY.java"); IType newY = renamedCU2.getType("NewY"); assertTrue("NewY should be present", newY.exists()); IField newBar = newX.getField("newBar"); assertTrue("Renamed field should exist", newBar.exists()); } /** * Ensures that a method can be renamed. */ public void testRenameMethod() throws JavaModelException { IType type = this.cu.getType("X"); IMethod method = type.getMethod("foo", new String[] {"QString;"}); renamePositive(method, "newFoo", false); //ensure that the method did not move as a result of the rename ensureCorrectPositioning( type, type.getMethod("newFoo", new String[] {"QString;"}), type.getMethod("otherMethod", new String[] {"QString;"})); } /** * Ensures that a method cannot be renamed to an existing method name. */ public void testRenameMethodResultingInCollision() { IType type = this.cu.getType("X"); IMethod method = type.getMethod("foo", new String[] {"QString;"}); renameNegative(method, "otherMethod", false, IJavaModelStatusConstants.NAME_COLLISION); } /** * Ensures that a method cannot be renamed to an invalid method name */ public void testRenameMethodsWithInvalidName() { IMethod method = this.cu.getType("X").getMethod("foo", new String[] {"QString;"}); renameNegative(method, "%%someInvalidName", false, IJavaModelStatusConstants.INVALID_NAME); } public void testRenamePF() throws CoreException { this.createFolder("/P/src/x/y/z"); this.createFile( "/P/src/x/y/z/A.java", "package x.y.z;\n" + "public class A {\n" + "}" ); IPackageFragment frag = getPackage("/P/src/x/y/z"); clearDeltas(); frag.rename("x.y.newZ", false, null); IPackageFragment newFrag = getPackage("/P/src/x/y/newZ"); assertTrue("Old package should not exist", !frag.exists()); assertTrue("New package should exist", newFrag.exists()); ICompilationUnit compilationUnit = newFrag.getCompilationUnit("A.java"); assertTrue("A.java should exits in new package", compilationUnit.exists()); IType[] types = compilationUnit.getTypes(); assertTrue(types != null && types.length == 1); IType mainType = types[0]; assertEquals( "Unexpected A.java's main type'", "x.y.newZ.A", mainType.getFullyQualifiedName()); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " x.y.newZ[+]: {MOVED_FROM(x.y.z [in src [in P]])}\n" + " x.y.z[-]: {MOVED_TO(x.y.newZ [in src [in P]])}" ); } /* * Ensures that renaming to a name containing spaces works * (regression test for bug 21957 'refactor rename' allows subpackage name to start with a space) */ public void testRenamePF2() throws CoreException { this.createFolder("/P/src/x/y/z"); this.createFile( "/P/src/x/y/z/A.java", "package x.y.z;\n" + "public class A {\n" + "}" ); IPackageFragment frag = getPackage("/P/src/x/y/z"); clearDeltas(); frag.rename("x.y. z2", false, null); IPackageFragment newFrag = getPackage("/P/src/x/y/z2"); assertTrue("Old package should not exist", !frag.exists()); assertTrue("New package should exist", newFrag.exists()); ICompilationUnit compilationUnit = newFrag.getCompilationUnit("A.java"); assertTrue("A.java should exits in new package", compilationUnit.exists()); IType[] types = compilationUnit.getTypes(); assertTrue(types != null && types.length == 1); IType mainType = types[0]; assertEquals( "Unexpected A.java's main type'", "x.y.z2.A", mainType.getFullyQualifiedName()); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " x.y.z2[+]: {MOVED_FROM(x.y.z [in src [in P]])}\n" + " x.y.z[-]: {MOVED_TO(x.y.z2 [in src [in P]])}" ); } /* * Ensure that renaming a package to a sub package and using IJavaProject#findType(...) in a IWorskpaceRunnable * finds the right type * (regression test for bug 83646 NPE renaming package) */ public void testRenamePF3() throws CoreException { createFolder("/P/src/x"); createFile( "/P/src/x/A.java", "package x;\n" + "public class A {\n" + "}" ); IWorkspaceRunnable runnable = new IWorkspaceRunnable(){ public void run(IProgressMonitor monitor) throws CoreException { getPackage("/P/src/x").rename("x.y", false, null); IType type = getJavaProject("P").findType("x.y.A"); assertTypesEqual( "Unepected type", "x.y.A\n", new IType[] {type}); } }; getWorkspace().run(runnable, null); } public void testRenamePFWithSubPackages() throws CoreException { this.createFolder("/P/src/x/y/z"); this.createFile( "/P/src/x/y/z/A.java", "package x.y.z;\n" + "public class A {\n" + "}" ); clearDeltas(); getPackage("/P/src/x").rename("newX", false, null); IPackageFragment oldFrag = getPackage("/P/src/x/y/z"); assertTrue("Old inner package should still exist", oldFrag.exists()); IPackageFragment newFrag = getPackage("/P/src/newX"); assertTrue("New package should exist", newFrag.exists()); ICompilationUnit compilationUnit = oldFrag.getCompilationUnit("A.java"); assertTrue("A.java should exits in old inner package", compilationUnit.exists()); assertDeltas( "Unexpected deltas", "P[*]: {CHILDREN}\n" + " src[*]: {CHILDREN}\n" + " newX[+]: {}" ); } /** * Ensures that a method can be renamed if it contains syntax errors. */ public void testRenameSyntaxErrorMethod() throws CoreException { this.createFile( "/P/src/Y.java", "public class Y {\n" + " void foo( {\n" + // syntax error " }\n" + "}" ); IMethod method = getCompilationUnit("/P/src/Y.java").getType("Y").getMethod("foo", null); renamePositive(method, "newFoo", false); } /** * Ensures that attempting to rename with an incorrect number of renamings fails */ public void testRenameWithInvalidRenamings() { IMethod method = getCompilationUnit("/P/src/X.java").getType("X").getMethod("foo", null); renameNegative( new IJavaElement[] {method}, new String[]{"", ""}, false, IJavaModelStatusConstants.INDEX_OUT_OF_BOUNDS); renameNegative( new IJavaElement[] {method}, null, false, IJavaModelStatusConstants.NULL_NAME); } /** * Ensures that a working copy cannot be renamed. */ public void testRenameWorkingCopy() throws JavaModelException { ICompilationUnit copy = null; try { copy = this.cu.getWorkingCopy(null); renameNegative(copy, "NewX", false, IJavaModelStatusConstants.INVALID_ELEMENT_TYPES); } finally { if (copy != null) copy.discardWorkingCopy(); } } }