package spoon.test.secondaryclasses;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static spoon.testing.utils.ModelUtils.build;
import static spoon.testing.utils.ModelUtils.buildClass;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import org.junit.Test;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.code.CtVariableRead;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtNamedElement;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtVariable;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.AbstractFilter;
import spoon.reflect.visitor.filter.NameFilter;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.comparator.CtLineElementComparator;
import spoon.test.secondaryclasses.AnonymousClass.I;
import spoon.test.secondaryclasses.testclasses.Pozole;
public class ClassesTest {
@Test
public void testClassWithInternalPublicClassOrInterf() throws Exception {
CtClass<?> type = build("spoon.test.secondaryclasses",
"ClassWithInternalPublicClassOrInterf");
assertEquals("ClassWithInternalPublicClassOrInterf",
type.getSimpleName());
assertEquals(3,
type.getElements(new TypeFilter<CtType<?>>(CtType.class))
.size());
assertEquals(2, type.getNestedTypes().size());
assertTrue(type
.getNestedTypes()
.contains(
(type.getFactory().Class()
.get(ClassWithInternalPublicClassOrInterf.InternalClass.class))));
assertEquals(
1,
type.getElements(
new NameFilter<CtNamedElement>("InternalInterf"))
.size());
}
@Test
public void testAnonymousClass() throws Exception {
CtClass<?> type = build("spoon.test.secondaryclasses", "AnonymousClass");
assertEquals("AnonymousClass", type.getSimpleName());
CtNewClass<?> x = type.getElements(
new TypeFilter<CtNewClass<?>>(CtNewClass.class)).get(0);
CtNewClass<?> y = type.getElements(
new TypeFilter<CtNewClass<?>>(CtNewClass.class)).get(1);
if (x.getParent() instanceof CtBlock) {
CtNewClass<?> z = x;
x = y;
y = z;
}
// names of anonymous classes
// classes should always have different names
CtClass<?> anonymousClass0 = x.getAnonymousClass();
CtClass<?> anonymousClass1 = y.getAnonymousClass();
assertEquals("1",anonymousClass0.getSimpleName());
assertEquals("2",anonymousClass1.getSimpleName());
assertEquals("spoon.test.secondaryclasses.AnonymousClass$1",anonymousClass0.getQualifiedName());
assertEquals("spoon.test.secondaryclasses.AnonymousClass$2",anonymousClass1.getQualifiedName());
// ActionListener is not in the Spoon path but we can build a shadow element.
assertNull(x.getType().getDeclaration());
assertNotNull(x.getType().getTypeDeclaration());
// but the actual class is known
assertEquals(ActionListener.class, x.getType().getActualClass());
assertNotNull(y.getType().getDeclaration());
assertEquals("spoon.test.secondaryclasses.AnonymousClass$2#2()", y.getExecutable().toString());
assertEquals(type.getFactory().Type().createReference(I.class), y.getAnonymousClass().getSuperInterfaces().toArray(new CtTypeReference[0])[0]);
}
@Test
public void testIsAnonymousMethodInCtClass() throws Exception {
CtClass<?> type = build("spoon.test.secondaryclasses", "AnonymousClass");
TreeSet<CtClass<?>> ts = new TreeSet<CtClass<?>>(new CtLineElementComparator());
ts.addAll(type.getElements(new AbstractFilter<CtClass<?>>(CtClass.class) {
@Override
public boolean matches(CtClass<?> element) {
return element.isAnonymous();
}
}));
List<CtClass<?>> anonymousClass = new ArrayList<CtClass<?>>();
anonymousClass.addAll(ts);
assertFalse(type.isAnonymous());
assertTrue(ts.first().isAnonymous());
assertTrue(anonymousClass.get(1).isAnonymous());
assertEquals(2, anonymousClass.size());
assertEquals(2, ts.size());
assertEquals("spoon.test.secondaryclasses.AnonymousClass$1", anonymousClass.get(0).getQualifiedName());
assertEquals("spoon.test.secondaryclasses.AnonymousClass$2", anonymousClass.get(1).getQualifiedName());
}
@Test
public void testTopLevel() throws Exception {
CtClass<?> type = build("spoon.test.secondaryclasses", "TopLevel");
assertEquals("TopLevel", type.getSimpleName());
CtClass<?> x = type.getElements(
new NameFilter<CtClass<?>>("InnerClass")).get(0);
List<CtField<?>> fields = x.getFields();
assertEquals(1, fields.size());
assertEquals(1, fields.get(0).getType().getActualTypeArguments().size());
assertEquals("?",
fields.get(0).getType().getActualTypeArguments().get(0)
.getSimpleName());
}
@Test
public void testInnerClassContruction() throws Exception {
Factory f = build(PrivateInnerClasses.class);
CtClass<?> c = f.Class().get(PrivateInnerClasses.class);
assertNotNull(c);
assertEquals(0, f.getEnvironment().getErrorCount());
}
@Test
public void testAnonymousClassInStaticField() throws Exception {
final CtType<Pozole> type = buildClass(Pozole.class);
final CtNewClass<?> anonymousClass = type.getField("CONFLICT_HOOK").getElements(new TypeFilter<>(CtNewClass.class)).get(1);
final CtVariableRead<?> ctVariableRead = anonymousClass.getElements(new TypeFilter<>(CtVariableRead.class)).get(2);
final CtVariable<?> declaration = ctVariableRead.getVariable().getDeclaration();
assertNotNull(declaration);
assertEquals("int i", declaration.toString());
}
}