/*
* Copyright 2014 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Eclipse Public License version 1.0, available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.jboss.forge.test.roaster.model;
import java.util.List;
import org.hamcrest.CoreMatchers;
import org.jboss.forge.roaster.Roaster;
import org.jboss.forge.roaster.model.source.Import;
import org.jboss.forge.roaster.model.source.JavaAnnotationSource;
import org.jboss.forge.roaster.model.source.JavaClassSource;
import org.jboss.forge.roaster.model.source.JavaEnumSource;
import org.jboss.forge.roaster.model.source.JavaInterfaceSource;
import org.jboss.forge.roaster.model.source.JavaSource;
import org.junit.Assert;
import org.junit.Test;
public class NestedClassTest
{
@Test
public void testImportNestedClass()
{
JavaClassSource javaClass = Roaster.create(JavaClassSource.class);
Import imprt = javaClass.addImport(NestedClass.class);
Assert.assertEquals("org.jboss.forge.test.roaster.model.NestedClassTest.NestedClass",
imprt.getQualifiedName());
}
@Test
public void testGetNestedClasses()
{
JavaClassSource javaClass = Roaster
.parse(JavaClassSource.class, "package org.example; public class OuterClass { " +
" public class InnerClass1{ " +
" public class InnerClass3{}" +
" } " +
" public class InnerClass2{} " +
"}");
Assert.assertEquals("org.example.OuterClass", javaClass.getCanonicalName());
List<JavaSource<?>> nestedClasses = javaClass.getNestedTypes();
JavaClassSource inner1 = (JavaClassSource) nestedClasses.get(0);
JavaClassSource inner2 = (JavaClassSource) nestedClasses.get(1);
JavaClassSource inner3 = (JavaClassSource) inner1.getNestedTypes().get(0);
Assert.assertEquals(javaClass, inner1.getEnclosingType());
Assert.assertEquals("org.example.OuterClass.InnerClass1", inner1.getCanonicalName());
Assert.assertEquals("org.example.OuterClass$InnerClass1", inner1.getQualifiedName());
Assert.assertEquals(javaClass, inner2.getEnclosingType());
Assert.assertEquals("InnerClass1", inner1.getName());
Assert.assertEquals("org.example.OuterClass.InnerClass2", inner2.getCanonicalName());
Assert.assertEquals("org.example.OuterClass$InnerClass2", inner2.getQualifiedName());
Assert.assertEquals("InnerClass2", inner2.getName());
Assert.assertEquals(2, nestedClasses.size());
Assert.assertEquals("org.example.OuterClass$InnerClass1$InnerClass3", inner3.getQualifiedName());
Assert.assertEquals("org.example.OuterClass.InnerClass1.InnerClass3", inner3.getCanonicalName());
}
@Test
public void testModifyNestedClassModifiesParentSource()
{
JavaClassSource javaClass = Roaster
.parse(JavaClassSource.class, "package org.example; public class OuterClass { " +
" public class InnerClass1{ " +
" public class InnerClass3{}" +
" } " +
" public class InnerClass2{} " +
"}");
List<JavaSource<?>> nestedClasses = javaClass.getNestedTypes();
JavaSource<?> inner1 = nestedClasses.get(0);
inner1.addAnnotation(Deprecated.class);
Assert.assertTrue(javaClass.toString().contains("@Deprecated"));
}
@Test
public void testInterfaceWithNestedClass()
{
JavaInterfaceSource javaInterface = Roaster
.parse(JavaInterfaceSource.class, "package org.example; public interface OuterInterface { " +
" public class InnerClass1{ " +
" public class InnerClass3{}" +
" } " +
" public class InnerClass2{} " +
"}");
Assert.assertEquals("org.example.OuterInterface", javaInterface.getCanonicalName());
List<JavaSource<?>> nestedClasses = javaInterface.getNestedTypes();
JavaClassSource inner1 = (JavaClassSource) nestedClasses.get(0);
JavaClassSource inner2 = (JavaClassSource) nestedClasses.get(1);
Assert.assertEquals(javaInterface, inner1.getEnclosingType());
Assert.assertEquals("org.example.OuterInterface.InnerClass1", inner1.getCanonicalName());
Assert.assertEquals("org.example.OuterInterface$InnerClass1", inner1.getQualifiedName());
Assert.assertEquals(javaInterface, inner2.getEnclosingType());
Assert.assertEquals("InnerClass1", inner1.getName());
Assert.assertEquals("org.example.OuterInterface.InnerClass2", inner2.getCanonicalName());
Assert.assertEquals("org.example.OuterInterface$InnerClass2", inner2.getQualifiedName());
Assert.assertEquals("InnerClass2", inner2.getName());
Assert.assertEquals(2, nestedClasses.size());
}
@Test
public void testEnumWithNestedClass()
{
JavaEnumSource javaEnum = Roaster
.parse(JavaEnumSource.class, "package org.example; public enum OuterEnum { " +
" FOO, BAR, BAZ; " +
" public class InnerClass1{ " +
" public class InnerClass3{}" +
" } " +
" public class InnerClass2{} " +
"}");
Assert.assertEquals("org.example.OuterEnum", javaEnum.getCanonicalName());
List<JavaSource<?>> nestedClasses = javaEnum.getNestedTypes();
JavaClassSource inner1 = (JavaClassSource) nestedClasses.get(0);
JavaClassSource inner2 = (JavaClassSource) nestedClasses.get(1);
Assert.assertEquals(javaEnum, inner1.getEnclosingType());
Assert.assertEquals("org.example.OuterEnum.InnerClass1", inner1.getCanonicalName());
Assert.assertEquals("org.example.OuterEnum$InnerClass1", inner1.getQualifiedName());
Assert.assertEquals(javaEnum, inner2.getEnclosingType());
Assert.assertEquals("InnerClass1", inner1.getName());
Assert.assertEquals("org.example.OuterEnum.InnerClass2", inner2.getCanonicalName());
Assert.assertEquals("org.example.OuterEnum$InnerClass2", inner2.getQualifiedName());
Assert.assertEquals("InnerClass2", inner2.getName());
Assert.assertEquals(2, nestedClasses.size());
}
@Test
public void testClassWithNestedEnum()
{
JavaClassSource javaClass = Roaster
.parse(JavaClassSource.class, "package org.example; "
+ "public class OuterClass { " +
" public enum InnerEnum{A,B,C;} " +
"}");
Assert.assertEquals("org.example.OuterClass", javaClass.getCanonicalName());
List<JavaSource<?>> nestedClasses = javaClass.getNestedTypes();
JavaEnumSource inner1 = (JavaEnumSource) nestedClasses.get(0);
Assert.assertEquals(javaClass, inner1.getEnclosingType());
Assert.assertEquals("org.example.OuterClass.InnerEnum", inner1.getCanonicalName());
Assert.assertEquals("org.example.OuterClass$InnerEnum", inner1.getQualifiedName());
Assert.assertEquals("InnerEnum", inner1.getName());
Assert.assertEquals(1, nestedClasses.size());
}
@Test
public void testAnnotationWithNestedClass()
{
JavaAnnotationSource javaAnnotation = Roaster
.parse(JavaAnnotationSource.class, "package org.example; public @interface OuterAnnotation { " +
" public class InnerClass1{ " +
" public class InnerClass3{}" +
" } " +
" public class InnerClass2{} " +
"}");
Assert.assertEquals("org.example.OuterAnnotation", javaAnnotation.getCanonicalName());
List<JavaSource<?>> nestedClasses = javaAnnotation.getNestedTypes();
JavaClassSource inner1 = (JavaClassSource) nestedClasses.get(0);
JavaClassSource inner2 = (JavaClassSource) nestedClasses.get(1);
Assert.assertEquals(javaAnnotation, inner1.getEnclosingType());
Assert.assertEquals("org.example.OuterAnnotation.InnerClass1", inner1.getCanonicalName());
Assert.assertEquals("org.example.OuterAnnotation$InnerClass1", inner1.getQualifiedName());
Assert.assertEquals(javaAnnotation, inner2.getEnclosingType());
Assert.assertEquals("InnerClass1", inner1.getName());
Assert.assertEquals("org.example.OuterAnnotation.InnerClass2", inner2.getCanonicalName());
Assert.assertEquals("org.example.OuterAnnotation$InnerClass2", inner2.getQualifiedName());
Assert.assertEquals("InnerClass2", inner2.getName());
Assert.assertEquals(2, nestedClasses.size());
}
@Test
public void testAddNestedAnnotationInAnnotation()
{
JavaAnnotationSource javaAnnotation = Roaster.create(JavaAnnotationSource.class);
JavaAnnotationSource nestedAnnotation = javaAnnotation.addNestedType(JavaAnnotationSource.class);
Assert.assertNotNull(nestedAnnotation);
nestedAnnotation.setName("List").addAnnotationElement().setName("value").setType("String[]");
Assert.assertTrue(javaAnnotation.hasNestedType(nestedAnnotation));
Assert.assertTrue(javaAnnotation.hasNestedType("List"));
JavaAnnotationSource nestedType = (JavaAnnotationSource) javaAnnotation.getNestedType("List");
Assert.assertEquals(nestedAnnotation, nestedType);
}
@Test
public void testRemoveNestedClassInClass()
{
JavaClassSource javaClass = Roaster
.parse(JavaClassSource.class, "package org.example; public class OuterClass { " +
" public class InnerClass1{ " +
" public class InnerClass3{}" +
" } " +
" public class InnerClass2{} " +
"}");
JavaSource<?> innerClass1 = javaClass.getNestedType("InnerClass1");
Assert.assertThat(innerClass1, CoreMatchers.instanceOf(JavaClassSource.class));
javaClass.removeNestedType(innerClass1);
Assert.assertFalse(javaClass.hasNestedType("InnerClass1"));
Assert.assertFalse(javaClass.hasNestedType(innerClass1));
Assert.assertEquals(1, javaClass.getNestedTypes().size());
}
@Test
public void testRenamedOuterClass() throws Exception
{
JavaClassSource source = Roaster
.parse(JavaClassSource.class,
"public class Outer {public class Inner { String innerField; public Inner() {} public Inner(String innerField){this.innerField=innerField;}} public Outer() {}}");
JavaClassSource nestedType = (JavaClassSource) source.getNestedType("Inner");
Assert.assertNotNull(nestedType);
Assert.assertEquals("Inner", nestedType.getName());
Assert.assertEquals(1, source.getMethods().size());
Assert.assertEquals(2, nestedType.getMethods().size());
Assert.assertTrue(source.getMethods().get(0).isConstructor());
Assert.assertEquals("Outer", source.getMethods().get(0).getName());
Assert.assertTrue(nestedType.getMethods().get(0).isConstructor());
Assert.assertTrue(nestedType.getMethods().get(1).isConstructor());
Assert.assertEquals("Inner", nestedType.getMethods().get(0).getName());
Assert.assertEquals("Inner", nestedType.getMethods().get(1).getName());
source.setName("RenamedOuter");
nestedType = (JavaClassSource) source.getNestedType("Inner");
Assert.assertTrue(source.getMethods().get(0).isConstructor());
Assert.assertEquals("RenamedOuter", source.getMethods().get(0).getName());
Assert.assertTrue(nestedType.getMethods().get(0).isConstructor());
Assert.assertTrue(nestedType.getMethods().get(1).isConstructor());
Assert.assertEquals("Inner", nestedType.getMethods().get(0).getName());
Assert.assertEquals("Inner", nestedType.getMethods().get(1).getName());
}
public class NestedClass
{
}
}