blob: 0d6011ce928d82c6f92032dcc1ec7642d3725884 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 IBM Corporation and others.
*
* 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
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.ui.tests.refactoring;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import org.junit.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.mapping.ModelProvider;
public class TestModelProvider extends ModelProvider {
private static class Sorter implements Comparator<IResourceDelta> {
@Override
public int compare(IResourceDelta d1, IResourceDelta d2) {
return d1.getResource().getFullPath().toPortableString().compareTo(
d2.getResource().getFullPath().toPortableString());
}
}
private static final Comparator<IResourceDelta> COMPARATOR= new Sorter();
public static IResourceDelta LAST_DELTA;
public static boolean IS_COPY_TEST;
private static final int PRE_DELTA_FLAGS= IResourceDelta.CONTENT | IResourceDelta.MOVED_TO |
IResourceDelta.MOVED_FROM | IResourceDelta.OPEN;
public static void clearDelta() {
LAST_DELTA= null;
}
@Override
public IStatus validateChange(IResourceDelta delta, IProgressMonitor pm) {
LAST_DELTA= delta;
return super.validateChange(delta, pm);
}
public static void assertTrue(IResourceDelta expected) {
Assert.assertNotNull(LAST_DELTA);
boolean res= assertTrue(expected, LAST_DELTA);
if (!res) {
Assert.assertEquals(printDelta(expected), printDelta(LAST_DELTA));
}
LAST_DELTA= null;
}
private static boolean assertTrue(IResourceDelta expected, IResourceDelta actual) {
assertEqual(expected.getResource(), actual.getResource());
int actualKind= actual.getKind();
int actualFlags= actual.getFlags();
// The real delta can't combine kinds so we remove it from the received one as well.
if ((actualKind & (IResourceDelta.ADDED | IResourceDelta.REMOVED)) != 0) {
actualKind= actualKind & ~IResourceDelta.CHANGED;
}
// The expected delta doesn't support copy from flag. So remove it
actualFlags= actualFlags & ~IResourceDelta.COPIED_FROM;
int expectKind= expected.getKind();
int expectedFlags= expected.getFlags() & PRE_DELTA_FLAGS;
if ((expectKind & IResourceDelta.ADDED) != 0 && (expectedFlags & IResourceDelta.MOVED_FROM) != 0) {
expectedFlags= expectedFlags & ~IResourceDelta.OPEN;
}
if (expectKind != actualKind || expectedFlags != actualFlags) {
return false;
}
IResourceDelta[] expectedChildren= getExpectedChildren(expected);
IResourceDelta[] actualChildren= getActualChildren(actual, expectedChildren);
if (expectedChildren.length != actualChildren.length) {
return false;
}
Arrays.sort(expectedChildren, COMPARATOR);
Arrays.sort(actualChildren, COMPARATOR);
for (int i= 0; i < expectedChildren.length; i++) {
boolean res= assertTrue(expectedChildren[i], actualChildren[i]);
if (!res) {
Assert.assertEquals(printDelta(expected), printDelta(actual));
}
}
return true;
}
private static String printDelta(IResourceDelta delta) {
StringBuffer buf= new StringBuffer();
appendDelta(delta, 0, buf);
return buf.toString();
}
private static StringBuffer appendDelta(IResourceDelta delta, int indent, StringBuffer buf) {
for (int i= 0; i < indent; i++) {
buf.append(" ");
}
buf.append(delta.getResource().toString());
buf.append("-").append(getKindString(delta.getKind()));
int flags= delta.getKind();
if (flags != 0) {
buf.append("-").append(getFlagString(flags)).append('\n');
}
IResourceDelta[] affectedChildren= delta.getAffectedChildren();
Arrays.sort(affectedChildren, COMPARATOR);
for (IResourceDelta resourcedelta : affectedChildren) {
appendDelta(resourcedelta, indent + 1, buf);
}
return buf;
}
private static String getKindString(int kind) {
switch (kind) {
case IResourceDelta.CHANGED:
return "CHANGED";
case IResourceDelta.ADDED:
return "ADDED";
case IResourceDelta.REMOVED:
return "REMOVED";
case IResourceDelta.ADDED_PHANTOM:
return "ADDED_PHANTOM";
case IResourceDelta.REMOVED_PHANTOM:
return "REMOVED_PHANTOM";
default:
return "NULL";
}
}
private static String getFlagString(int flags) {
StringBuffer buf= new StringBuffer();
appendFlag(flags, IResourceDelta.CONTENT, "CONTENT", buf);
appendFlag(flags, IResourceDelta.DESCRIPTION, "DESCRIPTION", buf);
appendFlag(flags, IResourceDelta.ENCODING, "ENCODING", buf);
appendFlag(flags, IResourceDelta.OPEN, "OPEN", buf);
appendFlag(flags, IResourceDelta.MOVED_TO, "MOVED_TO", buf);
appendFlag(flags, IResourceDelta.MOVED_FROM, "MOVED_FROM", buf);
appendFlag(flags, IResourceDelta.TYPE, "TYPE", buf);
appendFlag(flags, IResourceDelta.SYNC, "SYNC", buf);
appendFlag(flags, IResourceDelta.MARKERS, "MARKERS", buf);
appendFlag(flags, IResourceDelta.REPLACED, "REPLACED", buf);
return buf.toString();
}
private static void appendFlag(int flags, int flag, String name, StringBuffer res) {
if ((flags & flag) != 0) {
if (res.length() > 0) {
res.append("-");
}
res.append(name);
}
}
private static void assertEqual(IResource expected, IResource actual) {
// This is a simple approach to deal with renamed resources in the deltas.
// However it will not work if there is more than on child per delta since
// the children will be sorted and their order might change.
if (IS_COPY_TEST) {
IPath expectedPath= expected.getFullPath();
IPath actualPath= actual.getFullPath();
Assert.assertEquals("Same path length", expectedPath.segmentCount(), actualPath.segmentCount());
for(int i= 0; i < expectedPath.segmentCount(); i++) {
String expectedSegment= expectedPath.segment(i);
if (expectedSegment.startsWith("UnusedName") || "unusedName".equals(expectedSegment))
continue;
Assert.assertEquals("Different path segment", expectedSegment, actualPath.segment(i));
}
} else {
Assert.assertEquals("Same resource", expected, actual);
}
}
private static IResourceDelta[] getExpectedChildren(IResourceDelta delta) {
List<IResourceDelta> result= new ArrayList<>();
for (IResourceDelta child : delta.getAffectedChildren()) {
IResource resource= child.getResource();
if (resource != null && isIgnorable(resource))
continue;
if (child.getAffectedChildren().length > 0) {
result.add(child);
} else {
int flags= child.getFlags();
if (flags == 0 || (flags & PRE_DELTA_FLAGS) != 0) {
result.add(child);
}
}
}
return result.toArray(new IResourceDelta[result.size()]);
}
private static boolean isIgnorable(IResource resource) {
final String name= resource.getName();
if (resource.getType() != IResource.FOLDER)
return false;
return name.startsWith(".");
}
private static IResourceDelta[] getActualChildren(IResourceDelta delta, IResourceDelta[] expectedChildren) {
List<IResourceDelta> result= new ArrayList<>();
if (!IS_COPY_TEST) {
for (IResourceDelta resourcedelta : delta.getAffectedChildren()) {
IResource resource= resourcedelta.getResource();
if (resource != null && isIgnorable(resource))
continue;
result.add(resourcedelta);
}
} else {
for (IResourceDelta resourcedelta : delta.getAffectedChildren()) {
IResource resource= resourcedelta.getResource();
if (resource != null && isIgnorable(resource))
continue;
if (contains(expectedChildren, resourcedelta)) {
result.add(resourcedelta);
} else {
assertCopySource(resourcedelta);
}
}
}
return result.toArray(new IResourceDelta[result.size()]);
}
private static boolean contains(IResourceDelta[] expectedChildren, IResourceDelta actualDelta) {
IResource actualResource= actualDelta.getResource();
for (IResourceDelta resourcedelta : expectedChildren) {
if (isSameResourceInCopy(resourcedelta.getResource(), actualResource)) {
return true;
}
}
return false;
}
private static boolean isSameResourceInCopy(IResource expected, IResource actual) {
IPath expectedPath= expected.getFullPath();
IPath actualPath= actual.getFullPath();
if (expectedPath.segmentCount()!= actualPath.segmentCount())
return false;
for(int i= 0; i < expectedPath.segmentCount(); i++) {
String expectedSegment= expectedPath.segment(i);
if (expectedSegment.startsWith("UnusedName") || "unusedName".equals(expectedSegment))
continue;
if (!expectedSegment.equals(actualPath.segment(i)))
return false;
}
return true;
}
private static void assertCopySource(IResourceDelta delta) {
try {
delta.accept(d -> {
Assert.assertEquals("Not a copy delta", 0, (d.getKind() & ~IResourceDelta.CHANGED));
return true;
});
} catch (CoreException e) {
Assert.fail("Shouldn't happen");
}
}
}