/* * 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 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 org.junit.Assume.assumeFalse; import static org.junit.Assume.assumeTrue; import java.io.InputStream; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Set; import org.jboss.forge.roaster.Roaster; import org.jboss.forge.roaster.model.source.AnnotationSource; import org.jboss.forge.roaster.model.source.FieldSource; 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.jboss.forge.roaster.model.source.MethodSource; import org.jboss.forge.roaster.model.source.ParameterSource; import org.jboss.forge.roaster.model.source.PropertyHolderSource; import org.jboss.forge.roaster.model.source.PropertySource; import org.jboss.forge.roaster.model.util.Strings; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public class PropertiesTest<O extends JavaSource<O> & PropertyHolderSource<O>> { public enum PropertyComponent { FIELD { @Override String format(Class<?> type, String s) { return s; } }, ACCESSOR { @Override String format(Class<?> type, String s) { return (boolean.class.equals(type) ? "is" : "get") + Strings.capitalize(s); } }, MUTATOR { @Override String format(Class<?> type, String s) { return "set" + Strings.capitalize(s); } }; abstract String format(Class<?> type, String s); } @Parameters(name = "{2} {1}.{3}") public static List<Object[]> createParameters() { final List<Object[]> parameters = new ArrayList<Object[]>(); parameters.add(new Object[] { JavaClassSource.class, "MockClass", String.class, "field", EnumSet.of(PropertyComponent.FIELD) }); parameters.add(new Object[] { JavaEnumSource.class, "MockEnum", String.class, "field", EnumSet.of(PropertyComponent.FIELD) }); parameters.add(new Object[] { JavaInterfaceSource.class, "MockInterface", int.class, "count", EnumSet.of(PropertyComponent.ACCESSOR) }); parameters.add(new Object[] { JavaInterfaceSource.class, "BigInterface", boolean.class, "verbose", EnumSet.of(PropertyComponent.ACCESSOR, PropertyComponent.MUTATOR) }); return parameters; } @Parameter(0) public Class<O> sourceType; @Parameter(1) public String resourceName; @Parameter(2) public Class<?> type; @Parameter(3) public String name; @Parameter(4) public Set<PropertyComponent> existingItems; private O source; @Before public void reset() { final InputStream stream = JavaClassTest.class.getResourceAsStream(String.format( "/org/jboss/forge/grammar/java/%s.java", resourceName)); source = Roaster.parse(sourceType, stream); } @Test public void testHasProperty() { assertTrue(source.hasProperty(name)); assertFalse(source.hasProperty("noSuchProperty")); } @Test public void testGetPropertyByName() { PropertySource<O> property = source.getProperty(name); assertEquals(name, property.getName()); assertTrue(property.getType().isType(type)); } @Test public void testIsAccessible() { assertEquals(existingItems.contains(PropertyComponent.ACCESSOR), source.getProperty(name).isAccessible()); } @Test public void testIsMutable() { assertEquals(existingItems.contains(PropertyComponent.MUTATOR), source.getProperty(name).isMutable()); } @Test public void testHasField() { assertEquals(existingItems.contains(PropertyComponent.FIELD), source.getProperty(name).hasField()); } @Test public void testGetField() { final FieldSource<O> field = source.getProperty(name).getField(); if (!existingItems.contains(PropertyComponent.FIELD)) { assertNull(field); return; } assertNotNull(field); assertEquals(name, field.getName()); assertTrue(field.getType().isType(type)); } @Test public void testGetAccessor() { final MethodSource<O> accessor = source.getProperty(name).getAccessor(); if (!existingItems.contains(PropertyComponent.ACCESSOR)) { assertNull(accessor); return; } assertNotNull(accessor); assertEquals(PropertyComponent.ACCESSOR.format(type, name), accessor.getName()); assertTrue(accessor.getReturnType().isType(type)); } @Test public void testGetMutator() { final MethodSource<O> mutator = source.getProperty(name).getMutator(); if (!existingItems.contains(PropertyComponent.MUTATOR)) { assertNull(mutator); return; } assertNotNull(mutator); assertEquals(PropertyComponent.MUTATOR.format(type, name), mutator.getName()); assertTrue(mutator.isReturnTypeVoid()); assertEquals(1, mutator.getParameters().size()); assertTrue(mutator.getParameters().get(0).getType().isType(type)); } @Test public void testSetAccessibleTrue() { assumeFalse(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); property.setAccessible(true); assertTrue(property.isAccessible()); final MethodSource<O> accessor = property.getAccessor(); assertNotNull(accessor); assertTrue(source.hasMethod(accessor)); assertTrue(source.isInterface() || accessor.isPublic()); assertTrue(accessor.getReturnType().isType(type)); assertEquals(PropertyComponent.ACCESSOR.format(type, name), accessor.getName()); assertTrue(accessor.getParameters().isEmpty()); assertTrue(!existingItems.contains(PropertyComponent.FIELD) || accessor.getBody().contains(String.format("return %s;", name))); } @Test public void testSetMutableTrue() { assumeFalse(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); property.setMutable(true); final MethodSource<O> mutator = property.getMutator(); assertNotNull(mutator); assertTrue(source.hasMethod(mutator)); assertTrue(source.isInterface() || mutator.isPublic()); assertTrue(mutator.isReturnTypeVoid()); assertEquals(PropertyComponent.MUTATOR.format(type, name), mutator.getName()); assertEquals(1, mutator.getParameters().size()); final ParameterSource<O> parameter = mutator.getParameters().get(0); assertTrue(parameter.getType().isType(type)); assertEquals(name, parameter.getName()); assertTrue(!existingItems.contains(PropertyComponent.FIELD) || mutator.getBody().contains(String.format("this.%1$s=%1$s;", name))); } @Test(expected = IllegalStateException.class) public void testCreateFieldAgain() { source.getProperty(name).createField(); assertFalse(existingItems.contains(PropertyComponent.FIELD)); source.getProperty(name).createField(); } @Test public void testRemoveField() { assumeTrue(existingItems.contains(PropertyComponent.FIELD)); final FieldSource<O> field = source.getProperty(name).getField(); assertTrue(source.hasField(field)); source.getProperty(name).removeField(); assertFalse(source.hasField(field)); } @Test public void testSetAccessibleFalse() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertTrue(property.isAccessible()); final MethodSource<O> accessor = property.getAccessor(); assertNotNull(accessor); assertTrue(source.hasMethod(accessor)); property.setAccessible(false); assertFalse(property.isAccessible()); assertFalse(source.hasMethod(accessor)); } @Test public void testSetMutableFalse() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertTrue(property.isMutable()); final MethodSource<O> mutator = property.getMutator(); assertTrue(source.hasMethod(mutator)); if (existingItems.contains(PropertyComponent.FIELD)) { assertTrue(property.hasField()); assertNotNull(property.getField()); assertFalse(property.getField().isFinal()); } property.setMutable(false); assertFalse(source.hasMethod(mutator)); if (existingItems.contains(PropertyComponent.FIELD)) { assertTrue(property.hasField()); assertNotNull(property.getField()); assertTrue(property.getField().isFinal()); } } @Test public void testAddProperty() { final PropertySource<O> property = source.addProperty("Whatever", "blah"); assertEquals(property, source.getProperty("blah")); if (!source.isInterface()) { assertTrue(source.hasField("blah")); assertEquals("Whatever", source.getField("blah").getType().getName()); if (source.isEnum()) { assertTrue(source.getField("blah").isFinal()); } } final String accessorName = "getBlah"; assertTrue(source.hasMethodSignature(accessorName)); final MethodSource<O> accessor = source.getMethod(accessorName); assertEquals("Whatever", accessor.getReturnType().getName()); assertTrue(source.isInterface() || accessor.isPublic()); if (source.isEnum()) { return; } final String mutatorName = "setBlah"; assertTrue(source.hasMethodSignature(mutatorName, "Whatever")); final MethodSource<O> mutator = source.getMethod(mutatorName, "Whatever"); assertEquals("Whatever", mutator.getParameters().get(0).getType().getName()); assertTrue(source.isInterface() || mutator.isPublic()); } @Test public void testAddPropertyThenChangeType() { final PropertySource<O> property = source.addProperty("int", "something"); assertTrue(source.hasMethodSignature("getSomething")); assertTrue(source.getMethod("getSomething").getReturnType().isType(int.class)); property.setType(boolean.class); assertTrue(property.getType().isType(boolean.class)); assertFalse(source.hasMethodSignature("getSomething")); assertTrue(source.hasMethodSignature("isSomething")); assertTrue(source.getMethod("isSomething").getReturnType().isType(boolean.class)); } @Test public void testSetName() { assumeFalse("foo".equals(name)); assertEquals(existingItems.contains(PropertyComponent.FIELD), sourceHasPropertyField(name)); assertEquals(existingItems.contains(PropertyComponent.ACCESSOR), source.getMethod(PropertyComponent.ACCESSOR.format(type, name)) != null); assertEquals(existingItems.contains(PropertyComponent.MUTATOR), source.getMethod(PropertyComponent.MUTATOR.format(type, name), type) != null); final PropertySource<O> property = source.getProperty(name); if (!source.isInterface() && !property.hasField()) { property.createField(); } property.setAccessible(true); if (!source.isEnum() && !property.isMutable()) { property.createMutator(); } property.setName("foo"); assertEquals("foo", property.getName()); // make sure none of the original items remain: assertFalse(existingItems.contains(PropertyComponent.FIELD) && sourceHasPropertyField(name)); assertFalse(existingItems.contains(PropertyComponent.ACCESSOR) && source.getMethod(PropertyComponent.ACCESSOR.format(type, name)) != null); assertFalse(existingItems.contains(PropertyComponent.MUTATOR) && source.getMethod(PropertyComponent.MUTATOR.format(type, name), type) != null); assertTrue(source.isInterface() || sourceHasPropertyField("foo")); assertTrue(source.getMethod(PropertyComponent.ACCESSOR.format(type, "foo")) != null); assertTrue(source.isEnum() || source.getMethod(PropertyComponent.MUTATOR.format(type, "foo"), type) != null); if (property.hasField()) { assertTrue(property.getAccessor().getBody().contains("return foo;")); assertTrue(!property.isMutable() || property.getMutator().getBody().contains("this.foo=foo;")); } } @Test public void testSetTypeClass() { assumeFalse(CharSequence.class.equals(type)); final PropertySource<O> property = source.getProperty(name); property.setType(CharSequence.class); assertTrue(property.getType().isType(CharSequence.class)); assertTrue(!existingItems.contains(PropertyComponent.FIELD) || property.getField().getType().isType(CharSequence.class)); assertTrue(!existingItems.contains(PropertyComponent.ACCESSOR) || property.getAccessor().getReturnType().isType(CharSequence.class)); assertTrue(!existingItems.contains(PropertyComponent.MUTATOR) || property.getMutator().getParameters().get(0).getType().isType(CharSequence.class)); } @Test public void testSetTypeString() { assumeFalse(CharSequence.class.equals(type)); final PropertySource<O> property = source.getProperty(name); property.setType("CharSequence"); assertEquals("CharSequence", property.getType().getName()); assertTrue(!existingItems.contains(PropertyComponent.FIELD) || "CharSequence".equals(property.getField().getType().getName())); assertTrue(!existingItems.contains(PropertyComponent.ACCESSOR) || "CharSequence".equals(property.getAccessor().getReturnType().getName())); assertTrue(!existingItems.contains(PropertyComponent.MUTATOR) || "CharSequence".equals(property.getMutator().getParameters().get(0).getType().getName())); } @Test public void testSetTypeJavaType() { final PropertySource<O> property = source.getProperty(name); property.setType(source); assertEquals(source.getQualifiedName(), property.getType().getQualifiedName()); assertTrue(!existingItems.contains(PropertyComponent.FIELD) || Strings.areEqual(source.getQualifiedName(), property.getField().getType().getQualifiedName())); assertTrue(!existingItems.contains(PropertyComponent.ACCESSOR) || Strings .areEqual(source.getQualifiedName(), property.getAccessor().getReturnType().getQualifiedName())); assertTrue(!existingItems.contains(PropertyComponent.MUTATOR) || Strings.areEqual(source.getQualifiedName(), property.getMutator().getParameters().get(0).getType() .getQualifiedName())); } @Test public void testPropertySeesChangedAccessor() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertTrue(property.isAccessible()); property.getAccessor().setName("foo"); assertFalse(property.isAccessible()); } @Test public void testPropertySeesChangedMutator() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertTrue(property.isMutable()); property.getMutator().setName("foo"); assertFalse(property.isMutable()); } @Test public void testPropertyHasAnnotationField() { assumeTrue(existingItems.contains(PropertyComponent.FIELD)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getField().addAnnotation(Deprecated.class); assertTrue(property.hasAnnotation(Deprecated.class)); property.getField().removeAnnotation(ann); } @Test public void testPropertyHasAnnotationAccessor() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getAccessor().addAnnotation(Deprecated.class); assertTrue(property.hasAnnotation(Deprecated.class)); property.getAccessor().removeAnnotation(ann); } @Test public void testPropertyHasAnnotationMutator() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getMutator().addAnnotation(Deprecated.class); assertTrue(property.hasAnnotation(Deprecated.class)); property.getMutator().removeAnnotation(ann); } @Test public void testPropertyHasAnnotationTypeField() { assumeTrue(existingItems.contains(PropertyComponent.FIELD)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class.getName())); AnnotationSource<O> ann = property.getField().addAnnotation(Deprecated.class.getName()); assertTrue(property.hasAnnotation(Deprecated.class.getName())); property.getField().removeAnnotation(ann); } @Test public void testPropertyHasAnnotationTypeAccessor() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class.getName())); AnnotationSource<O> ann = property.getAccessor().addAnnotation(Deprecated.class.getName()); assertTrue(property.hasAnnotation(Deprecated.class.getName())); property.getAccessor().removeAnnotation(ann); } @Test public void testPropertyHasAnnotationTypeMutator() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class.getName())); AnnotationSource<O> ann = property.getMutator().addAnnotation(Deprecated.class.getName()); assertTrue(property.hasAnnotation(Deprecated.class.getName())); property.getMutator().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationTypeField() { assumeTrue(existingItems.contains(PropertyComponent.FIELD)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class.getName())); AnnotationSource<O> ann = property.getField().addAnnotation(Deprecated.class.getName()); assertNotNull(property.getAnnotation(Deprecated.class.getName())); property.getField().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationTypeAccessor() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class.getName())); AnnotationSource<O> ann = property.getAccessor().addAnnotation(Deprecated.class.getName()); assertNotNull(property.getAnnotation(Deprecated.class.getName())); property.getAccessor().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationTypeMutator() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class.getName())); AnnotationSource<O> ann = property.getMutator().addAnnotation(Deprecated.class.getName()); assertNotNull(property.getAnnotation(Deprecated.class.getName())); property.getMutator().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationField() { assumeTrue(existingItems.contains(PropertyComponent.FIELD)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getField().addAnnotation(Deprecated.class); assertNotNull(property.getAnnotation(Deprecated.class)); property.getField().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationAccessor() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getAccessor().addAnnotation(Deprecated.class); assertNotNull(property.getAnnotation(Deprecated.class)); property.getAccessor().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationMutator() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getMutator().addAnnotation(Deprecated.class); assertNotNull(property.getAnnotation(Deprecated.class)); property.getMutator().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationsField() { assumeTrue(existingItems.contains(PropertyComponent.FIELD)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getField().addAnnotation(Deprecated.class); assertEquals(1, property.getAnnotations().size()); property.getField().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationsAccessor() { assumeTrue(existingItems.contains(PropertyComponent.ACCESSOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getAccessor().addAnnotation(Deprecated.class); assertEquals(1, property.getAnnotations().size()); property.getAccessor().removeAnnotation(ann); } @Test public void testPropertyGetAnnotationsMutator() { assumeTrue(existingItems.contains(PropertyComponent.MUTATOR)); final PropertySource<O> property = source.getProperty(name); assertFalse(property.hasAnnotation(Deprecated.class)); AnnotationSource<O> ann = property.getMutator().addAnnotation(Deprecated.class); assertEquals(1, property.getAnnotations().size()); property.getMutator().removeAnnotation(ann); } private boolean sourceHasPropertyField(String fieldName) { if (source.isInterface()) { return false; } final FieldSource<O> field = source.getField(fieldName); return !(field == null || field.isStatic()); } }