blob: 58f7148d49d2e29636369d9481782d912a601138 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
*******************************************************************************/
package org.eclipse.dltk.core.tests.model;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.IModelElementDelta;
import org.eclipse.dltk.core.IParent;
import org.eclipse.dltk.core.IProjectFragment;
import org.eclipse.dltk.core.IScriptFolder;
import org.eclipse.dltk.core.ISourceManipulation;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.ModelException;
abstract public class CopyMoveTests extends ModifyingResourceTests {
public CopyMoveTests(String TestProjectName, String name) {
super(TestProjectName, name);
}
/**
* Attempts to copy the element with optional forcing. The operation should
* fail with the failure code.
*/
public void copyNegative(IModelElement element, IModelElement destination,
IModelElement sibling, String rename, boolean force, int failureCode) {
try {
((ISourceManipulation) element).copy(destination, sibling, rename,
force, null);
} catch (ModelException jme) {
assertTrue("Code not correct for ModelException: " + jme, jme
.getStatus().getCode() == failureCode);
return;
}
assertTrue("The copy should have failed for: " + element, false);
return;
}
/**
* Attempts to copy the elements with optional forcing. The operation should
* fail with the failure code.
*/
public void copyNegative(IModelElement[] elements,
IModelElement[] destinations, IModelElement[] siblings,
String[] renames, boolean force, int failureCode) {
try {
getScriptModel().copy(elements, destinations, siblings, renames,
force, null);
} catch (ModelException jme) {
assertTrue("Code not correct for ModelException: " + jme, jme
.getStatus().getCode() == failureCode);
return;
}
assertTrue("The move should have failed for for multiple elements: ",
false);
return;
}
/**
* Copies the element to the container with optional rename and forcing. The
* operation should succeed, so any exceptions encountered are thrown.
*/
public IModelElement copyPositive(IModelElement element,
IModelElement container, IModelElement sibling, String rename,
boolean force) throws ModelException {
// if forcing, ensure that a name collision exists
if (force) {
IModelElement collision = generateHandle(element, rename, container);
assertTrue("Collision does not exist", collision.exists());
}
IModelElement copy;
try {
startDeltas();
// copy
((ISourceManipulation) element).copy(container, sibling, rename,
force, null);
// ensure the original element still exists
assertTrue("The original element must still exist", element
.exists());
// generate the new element handle
copy = generateHandle(element, rename, container);
assertTrue("Copy should exist", copy.exists());
// ensure correct position
if (element.getElementType() > IModelElement.SOURCE_MODULE) {
ensureCorrectPositioning((IParent) container, sibling, copy);
} else {
if (container.getElementType() == IModelElement.PROJECT_FRAGMENT) {
} else {
// ensure package name is correct
//TODO: Add package declaration checks.
}
}
// if (copy.getElementType() == IModelElement.IMPORT_DECLARATION)
// container = ((ISourceModule) container).getImportContainer();
//TODO: Add import declarations check.
IModelElementDelta destDelta = getDeltaFor(container, true);
assertTrue("Destination container not changed", destDelta != null
&& destDelta.getKind() == IModelElementDelta.CHANGED);
IModelElementDelta[] deltas = destDelta.getAddedChildren();
assertTrue("Added children not correct for element copy", deltas[0]
.getElement().equals(copy));
} finally {
stopDeltas();
}
return copy;
}
/**
* Generates a new handle to the original element in its new container.
*/
public IModelElement generateHandle(IModelElement original, String rename,
IModelElement container) {
String name = original.getElementName();
if (rename != null) {
name = rename;
}
switch (container.getElementType()) {
case IModelElement.PROJECT_FRAGMENT:
switch (original.getElementType()) {
case IModelElement.SCRIPT_FOLDER:
return ((IProjectFragment) container)
.getScriptFolder(name);
default:
assertTrue("illegal child type", false);
break;
}
break;
case IModelElement.SCRIPT_FOLDER:
switch (original.getElementType()) {
case IModelElement.SOURCE_MODULE:
return ((IScriptFolder) container).getSourceModule(name);
default:
assertTrue("illegal child type", false);
break;
}
break;
case IModelElement.SOURCE_MODULE:
//TODO: Add import and package declarations check...
switch (original.getElementType()) {
// case IModelElement.IMPORT_DECLARATION:
// return ((ISourceModule) container).getImport(name);
// case IModelElement.PACKAGE_DECLARATION:
// return ((ISourceModule) container)
// .getPackageDeclaration(name);
case IModelElement.TYPE:
if (isMainType(original, container)) {
// the cu has been renamed as well
container = ((IScriptFolder) container.getParent())
.getSourceModule(name + ".java");
}
return ((ISourceModule) container).getType(name);
default:
assertTrue("illegal child type", false);
break;
}
break;
case IModelElement.TYPE:
switch (original.getElementType()) {
case IModelElement.METHOD:
if (name.equals(original.getParent().getElementName())) {
// method is a constructor
return ((IType) container).getMethod(container
.getElementName());
}
return ((IType) container).getMethod(name);
case IModelElement.FIELD:
return ((IType) container).getField(name);
case IModelElement.TYPE:
return ((IType) container).getType(name);
// case IModelElement.INITIALIZER:
// // hack to return the first initializer
// return ((IType) container).getInitializer(1);
default:
assertTrue("illegal child type", false);
break;
}
break;
default:
assertTrue("unsupported container type", false);
break;
}
assertTrue("should not get here", false);
return null;
}
/**
* Returns true if this element is the main type of its compilation unit.
*/
protected boolean isMainType(IModelElement element, IModelElement parent) {
if (parent instanceof ISourceModule) {
if (element instanceof IType) {
ISourceModule cu = (ISourceModule) parent;
String typeName = cu.getElementName();
typeName = typeName.substring(0, typeName.length() - 5);
return element.getElementName().equals(typeName)
&& element.getParent().equals(cu);
}
}
return false;
}
/**
* Attempts to move the element with optional forcing. The operation should
* fail with the failure code.
*/
public void moveNegative(IModelElement element, IModelElement destination,
IModelElement sibling, String rename, boolean force, int failureCode) {
try {
((ISourceManipulation) element).move(destination, sibling, rename,
force, null);
} catch (ModelException jme) {
assertTrue("Code not correct for ModelException: " + jme, jme
.getStatus().getCode() == failureCode);
return;
}
assertTrue("The move should have failed for: " + element, false);
return;
}
/**
* Attempts to move the element with optional forcing. The operation should
* fail with the failure code.
*/
public void moveNegative(IModelElement[] elements,
IModelElement[] destinations, IModelElement[] siblings,
String[] renames, boolean force, int failureCode) {
try {
getScriptModel().move(elements, destinations, siblings, renames,
force, null);
} catch (ModelException jme) {
assertTrue("Code not correct for ModelException: " + jme, jme
.getStatus().getCode() == failureCode);
return;
}
assertTrue("The move should have failed for for multiple elements: ",
false);
return;
}
/**
* Moves the element to the container with optional rename and forcing. The
* operation should succeed, so any exceptions encountered are thrown.
*/
public void movePositive(IModelElement element, IModelElement container,
IModelElement sibling, String rename, boolean force)
throws ModelException {
IModelElement[] siblings = new IModelElement[] { sibling };
String[] renamings = new String[] { rename };
if (sibling == null) {
siblings = null;
}
if (rename == null) {
renamings = null;
}
movePositive(new IModelElement[] { element },
new IModelElement[] { container }, siblings, renamings, force);
}
/**
* Moves the elements to the containers with optional renaming and forcing.
* The operation should succeed, so any exceptions encountered are thrown.
*/
public void movePositive(IModelElement[] elements,
IModelElement[] destinations, IModelElement[] siblings,
String[] names, boolean force) throws ModelException {
movePositive(elements, destinations, siblings, names, force, null);
}
/**
* Moves the elements to the containers with optional renaming and forcing.
* The operation should succeed, so any exceptions encountered are thrown.
*/
public void movePositive(IModelElement[] elements,
IModelElement[] destinations, IModelElement[] siblings,
String[] names, boolean force, IProgressMonitor monitor)
throws ModelException {
// if forcing, ensure that a name collision exists
int i;
if (force) {
for (i = 0; i < elements.length; i++) {
IModelElement e = elements[i];
IModelElement collision = null;
if (names == null) {
collision = generateHandle(e, null, destinations[i]);
} else {
collision = generateHandle(e, names[i], destinations[i]);
}
assertTrue("Collision does not exist", collision.exists());
}
}
try {
startDeltas();
// move
getScriptModel().move(elements, destinations, siblings, names, force,
monitor);
for (i = 0; i < elements.length; i++) {
IModelElement element = elements[i];
IModelElement moved = null;
if (names == null) {
moved = generateHandle(element, null, destinations[i]);
} else {
moved = generateHandle(element, names[i], destinations[i]);
}
// ensure the original element no longer exists, unless moving
// within the same container
if (!destinations[i].equals(element.getParent())) {
if (element.getElementType() == IModelElement.SCRIPT_FOLDER) {
// moving a package fragment does not necessary mean
// that it no longer exists
// it could have members that are not part of the Script
// Model
try {
IResource[] members = ((IContainer) element
.getUnderlyingResource()).members();
if (members.length == 0) {
assertTrue(
"The original element must not exist",
!element.exists());
}
} catch (CoreException ce) {
throw new ModelException(ce);
}
} else {
assertTrue("The original element must not exist",
!element.exists());
}
}
assertTrue("Moved element should exist", moved.exists());
// ensure correct position
if (element.getElementType() > IModelElement.SOURCE_MODULE) {
if (siblings != null && siblings.length > 0) {
ensureCorrectPositioning((IParent) moved.getParent(),
siblings[i], moved);
}
} else {
IModelElement container = destinations[i];
if (container.getElementType() == IModelElement.PROJECT_FRAGMENT) {
} else { // ensure package name is correct
//TODO: Add import declarations checking.
}
}
IModelElementDelta destDelta = null;
if (isMainType(element, destinations[i]) && names != null
&& names[i] != null) { // moved/renamed main type to
// same cu
destDelta = getDeltaFor(moved.getParent());
assertTrue(
"Renamed compilation unit as result of main type not added",
destDelta != null
&& destDelta.getKind() == IModelElementDelta.ADDED);
assertTrue("flag should be F_MOVED_FROM", (destDelta
.getFlags() & IModelElementDelta.F_MOVED_FROM) > 0);
assertTrue("moved from handle should be original",
destDelta.getMovedFromElement().equals(
element.getParent()));
} else {
destDelta = getDeltaFor(destinations[i], true);
assertTrue(
"Destination container not changed",
destDelta != null
&& destDelta.getKind() == IModelElementDelta.CHANGED);
IModelElementDelta[] deltas = destDelta.getAddedChildren();
assertTrue("Added children not correct for element copy",
deltas[i].getElement().equals(moved));
assertTrue("should be K_ADDED",
deltas[i].getKind() == IModelElementDelta.ADDED);
IModelElementDelta sourceDelta = getDeltaFor(element, false);
assertTrue("should be K_REMOVED",
sourceDelta.getKind() == IModelElementDelta.REMOVED);
}
}
} finally {
stopDeltas();
}
}
}