CommonWorldTests.java
/* *******************************************************************
* Copyright (c) 2002-2008 Contributors
* All rights reserved.
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v 2.0
* which accompanies this distribution and is available at
* https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
*
* Contributors:
* PARC initial implementation
* Andy Clement
* ******************************************************************/
package org.aspectj.weaver;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import junit.framework.TestCase;
import org.aspectj.testing.util.TestUtil;
/**
* An abstract set of tests that any World implementation should be able to pass. To run it against your World, subclass it and
* implement getWorld().
*
* @author Andy Clement
*/
public abstract class CommonWorldTests extends TestCase {
/**
* @return an instance of the World to be tested
*/
protected abstract World getWorld();
private World world;
@Override
public void setUp() {
world = getWorld();
}
private final UnresolvedType[] primitiveTypes = UnresolvedType.forSignatures(new String[] { "B", "S", "C", "I", "J", "F", "D",
"V" });
public void testPrimitiveTypes() {
ResolvedType[] primitives = world.resolve(primitiveTypes);
for (ResolvedType ty : primitives) {
modifiersTest(ty, Modifier.PUBLIC | Modifier.FINAL);
fieldsTest(ty, ResolvedMember.NONE);
methodsTest(ty, ResolvedMember.NONE);
interfacesTest(ty, ResolvedType.NONE);
superclassTest(ty, null);
pointcutsTest(ty, ResolvedMember.NONE);
isInterfaceTest(ty, false);
isClassTest(ty, false);
isAspectTest(ty, false);
for (ResolvedType ty1 : primitives) {
if (ty.equals(ty1)) {
isCoerceableFromTest(ty, ty1, true);
} else if (ty.equals(UnresolvedType.BOOLEAN) || ty1.equals(UnresolvedType.BOOLEAN)
|| ty.equals(UnresolvedType.VOID) || ty1.equals(UnresolvedType.VOID)) {
isCoerceableFromTest(ty, ty1, false);
} else {
isCoerceableFromTest(ty, ty1, true);
}
}
// Result of this depends on whether autoboxing is supported
// isCoerceableFromTest(ty, UnresolvedType.OBJECT, getSupportsAutoboxing());
primAssignTest("B", new String[]{});
primAssignTest("S", new String[]{"B"});
primAssignTest("C", new String[]{"B"});
primAssignTest("I", new String[]{"B", "S", "C"});
primAssignTest("J", new String[]{"B", "S", "C", "I"});
primAssignTest("F", new String[]{"B", "S", "C", "I", "J"});
primAssignTest("D", new String[]{"B", "S", "C", "I", "J", "F"});
primAssignTest("Z", new String[]{});
primAssignTest("V", new String[]{});
}
}
private void primAssignTest(String sig, String[] lowers) {
ResolvedType[] primitives = world.resolve(primitiveTypes);
UnresolvedType tx = UnresolvedType.forSignature(sig);
ResolvedType ty = world.resolve(tx, true);
assertTrue("Couldnt find type " + tx, !ty.isMissing());
ResolvedType[] lowerTyArray = world.resolve(UnresolvedType.forSignatures(lowers));
List<ResolvedType> lowerTys = new ArrayList<>(Arrays.asList(lowerTyArray));
lowerTys.add(ty);
Set<ResolvedType> allLowerTys = new HashSet<>(lowerTys);
Set<ResolvedType> allUpperTys = new HashSet<>(Arrays.asList(primitives));
allUpperTys.removeAll(allLowerTys);
for (ResolvedType other : allLowerTys) {
isAssignableFromTest(ty, other, true);
}
for (ResolvedType other : allUpperTys) {
isAssignableFromTest(ty, other, false);
}
}
public void testPrimitiveArrays() {
ResolvedType[] primitives = world.resolve(primitiveTypes);
for (ResolvedType ty : primitives) {
UnresolvedType tx = UnresolvedType.forSignature("[" + ty.getSignature());
// 'void[]' is an illegal type -> skip
if (tx.getSignature().equals("[V"))
continue;
ResolvedType aty = world.resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty.isMissing());
modifiersTest(aty, Modifier.PUBLIC | Modifier.FINAL);
fieldsTest(aty, ResolvedMember.NONE);
methodsTest(aty, ResolvedMember.NONE);
interfaceTest(
aty,
new ResolvedType[]{world.getCoreType(UnresolvedType.CLONEABLE),
world.getCoreType(UnresolvedType.SERIALIZABLE)});
superclassTest(aty, UnresolvedType.OBJECT);
pointcutsTest(aty, ResolvedMember.NONE);
isInterfaceTest(aty, false);
isClassTest(aty, false);
isAspectTest(aty, false);
for (ResolvedType ty1 : primitives) {
isCoerceableFromTest(aty, ty1, false);
tx = UnresolvedType.forSignature("[" + ty1.getSignature());
// 'void[]' is an illegal type -> skip
if (tx.getSignature().equals("[V"))
continue;
ResolvedType aty1 = getWorld().resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty1.isMissing());
if (ty.equals(ty1)) {
isCoerceableFromTest(aty, aty1, true);
isAssignableFromTest(aty, aty1, true);
} else {
isCoerceableFromTest(aty, aty1, false);
isAssignableFromTest(aty, aty1, false);
}
}
}
// double dimension arrays
for (ResolvedType ty : primitives) {
UnresolvedType tx = UnresolvedType.forSignature("[[" + ty.getSignature());
// 'void[][]' is an illegal type -> skip
if (tx.getSignature().equals("[[V"))
continue;
ResolvedType aty = world.resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty.isMissing());
modifiersTest(aty, Modifier.PUBLIC | Modifier.FINAL);
fieldsTest(aty, ResolvedMember.NONE);
methodsTest(aty, ResolvedMember.NONE);
interfaceTest(
aty,
new ResolvedType[]{world.getCoreType(UnresolvedType.CLONEABLE),
world.getCoreType(UnresolvedType.SERIALIZABLE)});
superclassTest(aty, UnresolvedType.OBJECT);
pointcutsTest(aty, ResolvedMember.NONE);
isInterfaceTest(aty, false);
isClassTest(aty, false);
isAspectTest(aty, false);
for (ResolvedType ty1 : primitives) {
isCoerceableFromTest(aty, ty1, false);
tx = UnresolvedType.forSignature("[[" + ty1.getSignature());
// 'void[][]' is an illegal type -> skip
if (tx.getSignature().equals("[[V"))
continue;
ResolvedType aty1 = getWorld().resolve(tx, true);
assertTrue("Couldnt find type " + tx, !aty1.isMissing());
if (ty.equals(ty1)) {
isCoerceableFromTest(aty, aty1, true);
isAssignableFromTest(aty, aty1, true);
} else {
isCoerceableFromTest(aty, aty1, false);
isAssignableFromTest(aty, aty1, false);
}
}
}
}
// ---- tests for parts of ResolvedType objects
protected void modifiersTest(ResolvedType ty, int mods) {
assertEquals(ty + " modifiers:", Modifier.toString(mods), Modifier.toString(ty.getModifiers()));
}
protected void fieldsTest(ResolvedType ty, Member[] x) {
TestUtil.assertSetEquals(ty + " fields:", x, ty.getDeclaredJavaFields());
}
protected void methodsTest(ResolvedType ty, Member[] x) {
TestUtil.assertSetEquals(ty + " methods:", x, ty.getDeclaredJavaMethods());
}
protected void mungersTest(ResolvedType ty, ShadowMunger[] x) {
List<ShadowMunger> l = ty.getDeclaredShadowMungers();
ShadowMunger[] array = (ShadowMunger[]) l.toArray(new ShadowMunger[0]);
TestUtil.assertSetEquals(ty + " mungers:", x, array);
}
protected void interfaceTest(ResolvedType type, ResolvedType[] expectedInterfaces) {
ResolvedType[] interfaces = type.getDeclaredInterfaces();
for (ResolvedType expectedInterface : expectedInterfaces) {
boolean wasMissing = true;
for (ResolvedType anInterface : interfaces) {
if (anInterface.getSignature().equals(expectedInterface.getSignature())) {
wasMissing = false;
}
}
if (wasMissing) {
fail("Expected declared interface " + expectedInterface + " but it wasn't found in "
+ Arrays.asList(interfaces));
}
}
}
protected void interfacesTest(ResolvedType ty, ResolvedType[] x) {
TestUtil.assertArrayEquals(ty + " interfaces:", x, ty.getDeclaredInterfaces());
}
protected void superclassTest(ResolvedType ty, UnresolvedType x) {
assertEquals(ty + " superclass:", x, ty.getSuperclass());
}
protected void pointcutsTest(ResolvedType ty, Member[] x) {
TestUtil.assertSetEquals(ty + " pointcuts:", x, ty.getDeclaredPointcuts());
}
protected void isInterfaceTest(ResolvedType ty, boolean x) {
assertEquals(ty + " is interface:", x, ty.isInterface());
}
protected void isAspectTest(ResolvedType ty, boolean x) {
assertEquals(ty + " is aspect:", x, ty.isAspect());
}
protected void isClassTest(ResolvedType ty, boolean x) {
assertEquals(ty + " is class:", x, ty.isClass());
}
protected void isCoerceableFromTest(UnresolvedType ty0, UnresolvedType ty1, boolean x) {
assertEquals(ty0 + " is coerceable from " + ty1, ty0.resolve(world).isCoerceableFrom(ty1.resolve(world)), x);
assertEquals(ty1 + " is coerceable from " + ty0, ty1.resolve(world).isCoerceableFrom(ty0.resolve(world)), x);
}
protected void isAssignableFromTest(UnresolvedType ty0, UnresolvedType ty1, boolean x) {
ResolvedType rty0 = ty0.resolve(world);
ResolvedType rty1 = ty1.resolve(world);
boolean result = rty0.isAssignableFrom(rty1);
assertEquals(ty0 + " is assignable from " + ty1, result, x);
}
// ---- tests for parts of ResolvedMethod objects
protected void modifiersTest(ResolvedMember m, int mods) {
assertEquals(m + " modifiers:", Modifier.toString(mods), Modifier.toString(m.getModifiers()));
}
protected void exceptionsTest(ResolvedMember m, UnresolvedType[] exns) {
TestUtil.assertSetEquals(m + " exceptions:", exns, m.getExceptions());
}
}