Updated Branches: refs/heads/master 6c8da1857 -> 37efe7eff
Convert TestNG to Spock Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/37efe7ef Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/37efe7ef Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/37efe7ef Branch: refs/heads/master Commit: 37efe7effd8e49d7dc9d402d3fba298d5c8d7a44 Parents: 6c8da18 Author: Howard M. Lewis Ship <[email protected]> Authored: Mon May 21 11:10:30 2012 -0700 Committer: Howard M. Lewis Ship <[email protected]> Committed: Mon May 21 11:10:30 2012 -0700 ---------------------------------------------------------------------- .../services/ClassPropertyAdapterImpl.java | 4 +- .../ioc/internal/services/PropertyAdapterImpl.java | 23 +- .../services/PropertyShadowBuilderImpl.java | 32 +- .../ioc/internal/services/ServiceMessages.java | 14 - .../internal/services/ServiceStrings.properties | 3 - .../services/PropertyAccessImplSpec.groovy | 708 +++++++++++++ .../ioc/services/GeneralIntegrationSpec.groovy | 26 + .../tapestry5/ioc/internal/services/Bean.java | 39 + .../ioc/internal/services/BeanSubclass.java | 25 + .../internal/services/PropertyAccessImplTest.java | 775 --------------- .../ioc/internal/services/PublicFieldBean.java | 7 + .../internal/services/ShadowedPublicFieldBean.java | 18 + .../apache/tapestry5/ioc/test/BeanSubclass.java | 25 - .../apache/tapestry5/ioc/test/TestBaseTest.java | 3 +- 14 files changed, 857 insertions(+), 845 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java index a7cf81d..b96a0c2 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassPropertyAdapterImpl.java @@ -1,4 +1,4 @@ -// Copyright 2006, 2007, 2008, 2010, 2011 The Apache Software Foundation +// Copyright 2006, 2007, 2008, 2010, 2011, 2012 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -82,7 +82,7 @@ public class ClassPropertyAdapterImpl implements ClassPropertyAdapter { String names = InternalUtils.joinSorted(adapters.keySet()); - return String.format("<ClassPropertyAdaptor %s : %s>", beanType.getName(), names); + return String.format("<ClassPropertyAdaptor %s: %s>", beanType.getName(), names); } public List<String> getPropertyNames() http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java index 67315b2..ced7bf2 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyAdapterImpl.java @@ -1,4 +1,4 @@ -// Copyright 2006, 2008, 2010 The Apache Software Foundation +// Copyright 2006, 2008, 2010, 2012 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -16,6 +16,7 @@ package org.apache.tapestry5.ioc.internal.services; import org.apache.tapestry5.ioc.AnnotationProvider; import org.apache.tapestry5.ioc.internal.util.CollectionFactory; +import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.ioc.services.ClassPropertyAdapter; import org.apache.tapestry5.ioc.services.PropertyAdapter; @@ -115,7 +116,9 @@ public class PropertyAdapterImpl implements PropertyAdapter public Object get(Object instance) { if (field == null && readMethod == null) - throw new UnsupportedOperationException(ServiceMessages.readNotSupported(instance, name)); + { + throw new UnsupportedOperationException(String.format("Class %s does not provide an accessor ('getter') method for property '%s'.", toClassName(instance), name)); + } Throwable fail; @@ -139,7 +142,12 @@ public class PropertyAdapterImpl implements PropertyAdapter public void set(Object instance, Object value) { if (field == null && writeMethod == null) - throw new UnsupportedOperationException(ServiceMessages.writeNotSupported(instance, name)); + { + throw new UnsupportedOperationException(String.format("Class %s does not provide a mutator ('setter') method for property '%s'.", + toClassName(instance), + name + )); + } Throwable fail; @@ -159,7 +167,14 @@ public class PropertyAdapterImpl implements PropertyAdapter fail = ex; } - throw new RuntimeException(ServiceMessages.writeFailure(name, instance, fail), fail); + throw new RuntimeException(String.format("Error updating property '%s' of %s: %s", + name, toClassName(instance), + InternalUtils.toMessage(fail)), fail); + } + + private String toClassName(Object instance) + { + return instance == null ? "<null>" : instance.getClass().getName(); } public <T extends Annotation> T getAnnotation(Class<T> annotationClass) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyShadowBuilderImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyShadowBuilderImpl.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyShadowBuilderImpl.java index fe09b1e..187f25f 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyShadowBuilderImpl.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/PropertyShadowBuilderImpl.java @@ -1,4 +1,4 @@ -// Copyright 2006, 2007, 2010, 2011 The Apache Software Foundation +// Copyright 2006, 2007, 2010, 2011, 2012 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,24 +14,10 @@ package org.apache.tapestry5.ioc.internal.services; +import org.apache.tapestry5.ioc.services.*; +import org.apache.tapestry5.plastic.*; + import java.lang.reflect.Method; -import java.lang.reflect.Modifier; - -import org.apache.tapestry5.ioc.services.Builtin; -import org.apache.tapestry5.ioc.services.PlasticProxyFactory; -import org.apache.tapestry5.ioc.services.PropertyAccess; -import org.apache.tapestry5.ioc.services.PropertyAdapter; -import org.apache.tapestry5.ioc.services.PropertyShadowBuilder; -import org.apache.tapestry5.plastic.ClassInstantiator; -import org.apache.tapestry5.plastic.Condition; -import org.apache.tapestry5.plastic.WhenCallback; -import org.apache.tapestry5.plastic.InstructionBuilder; -import org.apache.tapestry5.plastic.InstructionBuilderCallback; -import org.apache.tapestry5.plastic.MethodDescription; -import org.apache.tapestry5.plastic.PlasticClass; -import org.apache.tapestry5.plastic.PlasticClassTransformer; -import org.apache.tapestry5.plastic.PlasticField; -import org.apache.tapestry5.plastic.PlasticMethod; public class PropertyShadowBuilderImpl implements PropertyShadowBuilder { @@ -40,9 +26,9 @@ public class PropertyShadowBuilderImpl implements PropertyShadowBuilder private final PlasticProxyFactory proxyFactory; public PropertyShadowBuilderImpl(@Builtin - PlasticProxyFactory proxyFactory, + PlasticProxyFactory proxyFactory, - PropertyAccess propertyAccess) + PropertyAccess propertyAccess) { this.proxyFactory = proxyFactory; this.propertyAccess = propertyAccess; @@ -59,7 +45,11 @@ public class PropertyShadowBuilderImpl implements PropertyShadowBuilder throw new RuntimeException(ServiceMessages.noSuchProperty(sourceClass, propertyName)); if (!adapter.isRead()) - throw new RuntimeException(ServiceMessages.readNotSupported(source, propertyName)); + { + throw new RuntimeException( + String.format("Class %s does not provide an accessor ('getter') method for property '%s'.", + source.getClass().getName(), propertyName)); + } if (!propertyType.isAssignableFrom(adapter.getType())) throw new RuntimeException(ServiceMessages.propertyTypeMismatch(propertyName, sourceClass, http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java index f35aaa5..ad4c5b5 100644 --- a/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java +++ b/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ServiceMessages.java @@ -32,26 +32,12 @@ public class ServiceMessages return MESSAGES.format("no-such-property", clazz.getName(), propertyName); } - public static String readNotSupported(Object instance, String propertyName) - { - return MESSAGES.format("read-not-supported", instance.getClass().getName(), propertyName); - } - - public static String writeNotSupported(Object instance, String propertyName) - { - return MESSAGES.format("write-not-supported", instance.getClass().getName(), propertyName); - } public static String readFailure(String propertyName, Object instance, Throwable cause) { return MESSAGES.format("read-failure", propertyName, instance, cause); } - public static String writeFailure(String propertyName, Object instance, Throwable cause) - { - return MESSAGES.format("write-failure", propertyName, instance, cause); - } - public static String propertyTypeMismatch(String propertyName, Class sourceClass, Class propertyType, Class expectedType) { http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties b/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties index 2bc3922..b16ae75 100644 --- a/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties +++ b/tapestry-ioc/src/main/resources/org/apache/tapestry5/ioc/internal/services/ServiceStrings.properties @@ -13,10 +13,7 @@ # limitations under the License. no-such-property=Class %s does not contain a property named '%s'. -read-not-supported=Class %s does not provide an accessor ('getter') method for property '%s'. -write-not-supported=Class %s does not provide an mutator ('setter') method for property '%s'. read-failure=Error reading property '%s' of %s: %s -write-failure=Error updating property '%s' of %s: %s property-type-mismatch=Property '%s' of class %s is of type %s, which is not assignable to type %s. shutdown-listener-error=Error notifying %s of registry shutdown: %s recursive-symbol=Symbol '%s' is defined in terms of itself (%s). http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplSpec.groovy ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplSpec.groovy new file mode 100644 index 0000000..795f988 --- /dev/null +++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplSpec.groovy @@ -0,0 +1,708 @@ +package org.apache.tapestry5.ioc.internal.services + +import org.apache.tapestry5.beaneditor.DataType +import org.apache.tapestry5.beaneditor.Validate +import org.apache.tapestry5.ioc.annotations.Scope +import org.apache.tapestry5.ioc.internal.util.Pair +import org.apache.tapestry5.ioc.internal.util.StringLongPair +import org.apache.tapestry5.ioc.services.ClassPropertyAdapter +import org.apache.tapestry5.ioc.services.PropertyAccess + +import java.awt.Image +import java.lang.reflect.Method + +import spock.lang.* + +import java.beans.* + +class ExceptionBean { + + boolean getFailure() { + throw new RuntimeException("getFailure"); + } + + void setFailure(boolean b) { + throw new RuntimeException("setFailure"); + } + + @Override + String toString() { + return "PropertyAccessImplSpecBean"; + } +} + +class UglyBean { +} + +class UglyBeanBeanInfo implements BeanInfo { + + BeanInfo[] getAdditionalBeanInfo() { + return new BeanInfo[0]; + } + + BeanDescriptor getBeanDescriptor() { + return null; + } + + int getDefaultEventIndex() { + return 0; + } + + int getDefaultPropertyIndex() { + return 0; + } + + EventSetDescriptor[] getEventSetDescriptors() { + return new EventSetDescriptor[0]; + } + + Image getIcon(int iconKind) { + return null; + } + + MethodDescriptor[] getMethodDescriptors() { + return new MethodDescriptor[0]; + } + + PropertyDescriptor[] getPropertyDescriptors() { + throw new RuntimeException("This is the UglyBean."); + } + +} + +class ScalaBean { + + private String value; + + String getValue() { + return value; + } + + void setValue(String value) { + this.value = value; + } + + String value() { + return value; + } + + void value_$eq(String value) { + this.value = value; + } +} + +class ScalaClass { + + private String value; + + String value() { + return value; + } + + void value_$eq(String value) { + this.value = value; + } +} + +interface BeanInterface { + + String getValue(); + + void setValue(String v); + + String getOtherValue(); + + void setOtherValue(String v); + + int getIntValue(); // read-only +} + +abstract class AbstractBean implements BeanInterface { + // abstract class implements method from interface + private String other; + + String getOtherValue() { + return other; + } + + void setOtherValue(String v) { + other = v; + } +} + +class ConcreteBean extends AbstractBean { + + private String value; + private int intValue; + + ConcreteBean(int intValue) { + this.intValue = intValue; + } + + String getValue() { + return value; + } + + void setValue(String v) { + value = v; + } + + int getIntValue() { + return intValue; + } +} + +abstract class GenericBean<T> { + + public T value; +} + +class GenericStringBean extends GenericBean<String> { +} + +class PropertyAccessImplSpec extends Specification { + + @Shared + PropertyAccess access = new PropertyAccessImpl() + + @Shared + Random random = new Random() + + def "simple read access to a standard bean"() { + Bean b = new Bean() + int value = random.nextInt() + + when: + + b.value = value + + then: + + access.get(b, "value") == value + } + + def "property name access is case insensitive"() { + Bean b = new Bean() + int value = random.nextInt() + + when: + + b.value = value + + then: + + access.get(b, "VaLUe") == value + } + + def "simple write access to a standard bean"() { + Bean b = new Bean() + int value = random.nextInt() + + when: + + access.set(b, "value", value) + + then: + + b.value == value + } + + def "missing properties are an exception"() { + Bean b = new Bean() + + when: + + access.get(b, "zaphod") + + then: + + IllegalArgumentException e = thrown() + + e.message == "Class ${b.class.name} does not contain a property named 'zaphod'." + } + + def "it is not possible to update a read-only property"() { + Bean b = new Bean() + + when: + + access.set(b, "class", null) + + then: + + UnsupportedOperationException e = thrown() + + e.message == "Class ${b.class.name} does not provide a mutator ('setter') method for property 'class'." + } + + def "it is not possible to read a write-only property"() { + Bean b = new Bean() + + when: + + access.get(b, "writeOnly") + + then: + + UnsupportedOperationException e = thrown() + + e.message == "Class ${b.class.name} does not provide an accessor ('getter') method for property 'writeOnly'." + } + + def "when a getter method throws an exception, the exception is wrapped and rethrown"() { + + ExceptionBean b = new ExceptionBean() + + when: + + access.get(b, "failure") + + then: + + RuntimeException e = thrown() + + e.message == "Error reading property 'failure' of ${b}: getFailure" + } + + def "when a setter method throws an exception, the exception is wrapped and rethrown"() { + ExceptionBean b = new ExceptionBean() + + when: + + access.set(b, "failure", false) + + then: + + RuntimeException e = thrown() + + e.message == "Error updating property 'failure' of ${b.class.name}: setFailure" + } + + @Ignore + def "exception throw when introspecting the class is wrapped and rethrown"() { + + // Due to Groovy, the exception gets thrown here, not inside + // the access.get() method, thus @Ingore (for now) + + UglyBean b = new UglyBean() + + when: + + access.get(b, "google") + + then: + + RuntimeException e = thrown() + + e.message == "java.lang.RuntimeException: This is the UglyBean." + } + + def "clearCache() wipes internal cache"() { + when: + + ClassPropertyAdapter cpa1 = access.getAdapter Bean + + then: + + cpa1.is(access.getAdapter(Bean)) + + + when: + + access.clearCache() + + then: + + !cpa1.is(access.getAdapter(Bean)) + } + + def "ClassPropertyAdapter has a useful toString()"() { + + when: + + def cpa = access.getAdapter Bean + + then: + + cpa.toString() == "<ClassPropertyAdaptor ${Bean.class.name}: PI, class, readOnly, value, writeOnly>" + } + + @Unroll + def "expected properties for #beanClass.name property '#propertyName' are read=#read, update=#update, castRequired=#castRequired"() { + + when: + + def pa = getPropertyAdapter beanClass, propertyName + + then: + + pa.read == read + pa.update == update + pa.castRequired == castRequired + pa.writeMethod == writeMethod + pa.readMethod == readMethod + + where: + + beanClass | propertyName | read | update | castRequired | writeMethodName | readMethodName + Bean | "readOnly" | true | false | false | null | "getReadOnly" + Bean | "writeOnly" | false | true | false | "setWriteOnly" | null + Bean | "pi" | true | false | false | null | null + + writeMethod = findMethod beanClass, writeMethodName + readMethod = findMethod beanClass, readMethodName + } + + def "PropertyAdapter for unknown property name is null"() { + when: + + ClassPropertyAdapter cpa = access.getAdapter(Bean) + + then: + + cpa.getPropertyAdapter("google") == null + } + + @Unroll + def "PropertyAdapter.type for #beanClass.name property '#propertyName' is #type.name"() { + + ClassPropertyAdapter cpa = access.getAdapter(beanClass) + + when: + + def adapter = cpa.getPropertyAdapter(propertyName) + + then: + + adapter.type.is(type) + + where: + + beanClass | propertyName | type + Bean | "value" | int + Bean | "readOnly" | String + Bean | "writeOnly" | boolean + } + + def "ClassPropertyAdapter gives access to property names (in sorted order)"() { + ClassPropertyAdapter cpa = access.getAdapter(Bean) + + expect: + + cpa.propertyNames == ["PI", "class", "readOnly", "value", "writeOnly"] + } + + def "public static fields are treated as properties"() { + when: + + def adapter =getPropertyAdapter Bean, "pi" + + then: + + adapter.get(null).is(Bean.PI) + } + + def "public final static fields may not be updated"() { + def adapter =getPropertyAdapter Bean, "pi" + + when: + + adapter.set(null, 3.0d) + + then: + + RuntimeException e = thrown() + + e.message.contains "final" + e.message.contains "PI" + } + + def "super interface methods are inherited by sub-interface"() { + when: + + ClassPropertyAdapter cpa = access.getAdapter SubInterface + + then: + + cpa.propertyNames == ["grandParentProperty", "parentProperty", "subProperty"] + } + + def "indexed properties are ignored"() { + when: + + ClassPropertyAdapter cpa = access.getAdapter BeanWithIndexedProperty + + then: + + cpa.propertyNames == ["class", "primitiveProperty"] + } + + def "getAnnotation() when annotation is not present is null"() { + + when: + + def pa = getPropertyAdapter AnnotatedBean, "readWrite" + + then: + + pa.getAnnotation(Scope) == null + } + + def "getAnnotation() with annotation on setter method"() { + + when: + + def pa = getPropertyAdapter AnnotatedBean, "annotationOnWrite" + + then: + + pa.getAnnotation(Scope).value() == "onwrite" + } + + def "annotation on getter method overrides annotation on setter method"() { + def pa =getPropertyAdapter AnnotatedBean, "annotationOnRead" + + when: + + Scope annotation = pa.getAnnotation(Scope) + + then: + + annotation.value() == "onread" + } + + def "getAnnotation() works on read-only properties, skipping the missing setter method"() { + + when: + + def pa = getPropertyAdapter AnnotatedBean, "readOnly" + + then: + + pa.getAnnotation(Scope) == null + } + + def "annotations directly on fields are located"() { + when: + + def pa = access.getAdapter(Bean).getPropertyAdapter("value") + + then: + + pa.getAnnotation(DataType).value() == "fred" + } + + @Issue("TAPESTY-2448") + def "getAnnotation() will find annotations from an inherited field in a super-class"() { + when: + + def pa = getPropertyAdapter BeanSubclass, "value" + + then: + + pa.getAnnotation(DataType).value() == "fred" + } + + def "annotations on a getter or setter method override annotations on the field"() { + when: + + def pa = getPropertyAdapter Bean, "value" + + then: + + pa.getAnnotation(Validate).value() == "getter-value-overrides" + } + + def "PropertyAdapter.type understands (simple) generic signatures"() { + def cpa1 = access.getAdapter(StringLongPair) + + when: + + def key = cpa1.getPropertyAdapter("key") + + then: + + key.type == String + key.castRequired + key.declaringClass == Pair + + when: + + def value = cpa1.getPropertyAdapter("value") + + then: + + value.type == Long + value.castRequired + + when: + + def cpa2 = access.getAdapter(Pair) + def pkey = cpa2.getPropertyAdapter("key") + + then: + + pkey.type == Object + !pkey.castRequired + + when: + + def pvalue = cpa2.getPropertyAdapter("value") + + then: + + pvalue.type == Object + !pvalue.castRequired + } + + def "PropertyAdapter prefers JavaBeans property method names to Scala method names"() { + when: + + def pa = getPropertyAdapter ScalaBean, "value" + + then: + + pa.readMethod.name == "getValue" + pa.writeMethod.name == "setValue" + } + + def "PropertyAdapter understands Scala accessor method naming"() { + when: + + def pa = getPropertyAdapter ScalaClass, "value" + + then: + + pa.readMethod.name == "value" + pa.writeMethod.name == 'value_$eq' + } + + def "PropertyAccess exposes public fields as if they were properties"() { + when: + + def pa = getPropertyAdapter PublicFieldBean, "value" + + then: + + pa.field + pa.read + pa.update + + when: + + PublicFieldBean bean = new PublicFieldBean() + + pa.set(bean, "fred") + + then: + + bean.value == "fred" + + when: + + bean.value = "barney" + + then: + + pa.get(bean) == "barney" + } + + def "access to property is favored over public field when the names are the same"() { + def bean = new ShadowedPublicFieldBean() + + when: + + def pa = getPropertyAdapter ShadowedPublicFieldBean, "value" + + then: + + !pa.field + + when: + + pa.set(bean, "fred") + + then: + + bean.@value == null + + when: + + bean.@value = "barney" + bean.value = "wilma" + + then: + + pa.get(bean) == "wilma" + } + + def "a property defined by an unimplemented inteface method of an abstract class is accessible"() { + AbstractBean bean = new ConcreteBean(33) + def ca = access.getAdapter(AbstractBean) + + when: + + def va = ca.getPropertyAdapter("value") + + then: + + !va.field + + when: + + va.set(bean, "hello") + + then: + + va.get(bean) == "hello" + bean.value == "hello" + + when: + + def ova = ca.getPropertyAdapter("otherValue") + + then: + + !ova.field + + when: + + ova.set(bean, "other value") + + then: + + ova.get(bean) == "other value" + bean.otherValue == "other value" + + when: + + def iva = ca.getPropertyAdapter("intvalue") + + then: + + iva.get(bean) == 33 + iva.read + !iva.update + !iva.field + } + + def "generic field is recognized"() { + when: + def pa = getPropertyAdapter GenericStringBean, "value" + + then: + + pa.castRequired + pa.type == String + pa.declaringClass == GenericBean + } + + + def getPropertyAdapter(clazz, name) { + access.getAdapter(clazz).getPropertyAdapter(name) + } + + private Method findMethod(Class beanClass, String methodName) { + return beanClass.methods.find { it.name == methodName } + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/services/GeneralIntegrationSpec.groovy ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/services/GeneralIntegrationSpec.groovy b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/services/GeneralIntegrationSpec.groovy new file mode 100644 index 0000000..d9c217c --- /dev/null +++ b/tapestry-ioc/src/test/groovy/org/apache/tapestry5/ioc/services/GeneralIntegrationSpec.groovy @@ -0,0 +1,26 @@ +package org.apache.tapestry5.ioc.services + +import org.apache.tapestry5.ioc.AbstractSharedRegistrySpecification +import org.apache.tapestry5.ioc.internal.services.Bean + + +class GeneralIntegrationSpec extends AbstractSharedRegistrySpecification { + + def "PropertyAccess service is available"() { + + PropertyAccess pa = getService "PropertyAccess", PropertyAccess + + Bean b = new Bean() + + when: + + pa.set(b, "value", 99) + + then: + + b.value == 99 + pa.get(b, "value") == 99 + } + + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/Bean.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/Bean.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/Bean.java new file mode 100644 index 0000000..3fae5a6 --- /dev/null +++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/Bean.java @@ -0,0 +1,39 @@ +package org.apache.tapestry5.ioc.internal.services; + +import org.apache.tapestry5.beaneditor.DataType; +import org.apache.tapestry5.beaneditor.Validate; + +public class Bean +{ + public static final Double PI = 3.14; + + @DataType("fred") + @Validate("field-value-overridden") + private int value; + + @Validate("getter-value-overrides") + public int getValue() + { + return value; + } + + public void setValue(int value) + { + this.value = value; + } + + @Override + public String toString() + { + return "PropertyAccessImplSpecBean"; + } + + public void setWriteOnly(boolean b) + { + } + + public String getReadOnly() + { + return null; + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/BeanSubclass.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/BeanSubclass.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/BeanSubclass.java new file mode 100644 index 0000000..62bffe3 --- /dev/null +++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/BeanSubclass.java @@ -0,0 +1,25 @@ +// Copyright 2008 The Apache Software Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package org.apache.tapestry5.ioc.internal.services; + +public class BeanSubclass extends Bean +{ + private boolean flag; + + public boolean isFlag() + { + return flag; + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java deleted file mode 100644 index ff00019..0000000 --- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PropertyAccessImplTest.java +++ /dev/null @@ -1,775 +0,0 @@ -// Copyright 2006, 2007, 2008, 2010 The Apache Software Foundation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package org.apache.tapestry5.ioc.internal.services; - -import org.apache.tapestry5.beaneditor.DataType; -import org.apache.tapestry5.beaneditor.Validate; -import org.apache.tapestry5.ioc.Registry; -import org.apache.tapestry5.ioc.annotations.Scope; -import org.apache.tapestry5.ioc.internal.IOCInternalTestCase; -import org.apache.tapestry5.ioc.internal.util.Pair; -import org.apache.tapestry5.ioc.internal.util.StringLongPair; -import org.apache.tapestry5.ioc.services.ClassPropertyAdapter; -import org.apache.tapestry5.ioc.services.PropertyAccess; -import org.apache.tapestry5.ioc.services.PropertyAdapter; -import org.testng.annotations.Test; - -import java.awt.*; -import java.beans.*; -import java.util.Arrays; -import java.util.Random; - -public class PropertyAccessImplTest extends IOCInternalTestCase -{ - private static final String CLASS_NAME = PropertyAccessImplTest.class.getName(); - - private PropertyAccess access = new PropertyAccessImpl(); - - private Random random = new Random(); - - public static class Bean - { - public static final Double PI = 3.14; - - @DataType("fred") - @Validate("field-value-overridden") - private int value; - - @Validate("getter-value-overrides") - public int getValue() - { - return value; - } - - public void setValue(int value) - { - this.value = value; - } - - @Override - public String toString() - { - return "PropertyUtilsTestBean"; - } - - public void setWriteOnly(boolean b) - { - } - - public String getReadOnly() - { - return null; - } - } - - public static class BeanSubclass extends Bean - { - - } - - public static class ExceptionBean - { - public boolean getFailure() - { - throw new RuntimeException("getFailure"); - } - - public void setFailure(boolean b) - { - throw new RuntimeException("setFailure"); - } - - @Override - public String toString() - { - return "PropertyUtilsExceptionBean"; - } - } - - public static class UglyBean - { - } - - public static class UglyBeanBeanInfo implements BeanInfo - { - - public BeanInfo[] getAdditionalBeanInfo() - { - return new BeanInfo[0]; - } - - public BeanDescriptor getBeanDescriptor() - { - return null; - } - - public int getDefaultEventIndex() - { - return 0; - } - - public int getDefaultPropertyIndex() - { - return 0; - } - - public EventSetDescriptor[] getEventSetDescriptors() - { - return new EventSetDescriptor[0]; - } - - public Image getIcon(int iconKind) - { - return null; - } - - public MethodDescriptor[] getMethodDescriptors() - { - return new MethodDescriptor[0]; - } - - public PropertyDescriptor[] getPropertyDescriptors() - { - throw new RuntimeException("This is the UglyBean."); - } - - } - - public static class ScalaBean - { - private String value; - - public String getValue() - { - return value; - } - - public void setValue(String value) - { - this.value = value; - } - - public String value() - { - return value; - } - - public void value_$eq(String value) - { - this.value = value; - } - } - - public static class ScalaClass - { - private String value; - - public String value() - { - return value; - } - - public void value_$eq(String value) - { - this.value = value; - } - } - - public static class BooleanHolder - { - private boolean flag; - - public boolean isFlag() - { - return flag; - } - - public void setFlag(boolean flag) - { - this.flag = flag; - } - } - - public static class PublicFieldBean - { - public String value; - } - - public static class ShadowedPublicFieldBean - { - private String _value; - - public String value; - - public String getValue() - { - return _value; - } - - public void setValue(String value) - { - _value = value; - } - } - - public static abstract class GenericBean<T> - { - public T value; - } - - public static class GenericStringBean extends GenericBean<String> - { - } - - public static interface BeanInterface - { - String getValue(); - - void setValue(String v); - - String getOtherValue(); - - void setOtherValue(String v); - - int getIntValue(); // read-only - } - - public static abstract class AbstractBean implements BeanInterface - { - // abstract class implements method from interface - private String other; - - public String getOtherValue() - { - return other; - } - - public void setOtherValue(String v) - { - other = v; - } - } - - public static class ConcreteBean extends AbstractBean - { - private String value; - private int intValue; - - public ConcreteBean(int intValue) - { - this.intValue = intValue; - } - - public String getValue() - { - return value; - } - - public void setValue(String v) - { - value = v; - } - - public int getIntValue() - { - return intValue; - } - } - - @Test - public void simple_read_access() - { - Bean b = new Bean(); - - int value = random.nextInt(); - - b.setValue(value); - - assertEquals(access.get(b, "value"), value); - } - - @Test - public void property_name_case_is_ignored_on_read() - { - Bean b = new Bean(); - - int value = random.nextInt(); - - b.setValue(value); - - assertEquals(access.get(b, "VALUE"), value); - } - - @Test - public void simple_write_access() - { - Bean b = new Bean(); - - int value = random.nextInt(); - - access.set(b, "value", value); - - assertEquals(b.getValue(), value); - } - - @Test - public void property_name_case_is_ignored_on_write() - { - Bean b = new Bean(); - - int value = random.nextInt(); - - access.set(b, "VALUE", value); - - assertEquals(b.getValue(), value); - } - - @Test - public void missing_property() - { - Bean b = new Bean(); - - try - { - access.get(b, "zaphod"); - - unreachable(); - } catch (IllegalArgumentException ex) - { - assertEquals(ex.getMessage(), "Class " + CLASS_NAME + "$Bean does not " - + "contain a property named 'zaphod'."); - } - } - - @Test - public void attempt_to_update_read_only_property() - { - Bean b = new Bean(); - - try - { - access.set(b, "class", null); - unreachable(); - } catch (UnsupportedOperationException ex) - { - assertEquals(ex.getMessage(), "Class " + CLASS_NAME - + "$Bean does not provide an mutator ('setter') method for property 'class'."); - } - } - - @Test - public void attempt_to_read_from_write_only_property() - { - Bean b = new Bean(); - - try - { - access.get(b, "writeOnly"); - unreachable(); - } catch (UnsupportedOperationException ex) - { - assertEquals(ex.getMessage(), "Class " + CLASS_NAME - + "$Bean does not provide an accessor ('getter') method for property 'writeOnly'."); - } - } - - @Test - public void exception_thrown_inside_getter() - { - ExceptionBean b = new ExceptionBean(); - - try - { - access.get(b, "failure"); - unreachable(); - } catch (RuntimeException ex) - { - assertEquals(ex.getMessage(), "Error reading property 'failure' of PropertyUtilsExceptionBean: getFailure"); - } - } - - @Test - public void exception_thrown_inside_setter() - { - ExceptionBean b = new ExceptionBean(); - - try - { - access.set(b, "failure", false); - unreachable(); - } catch (RuntimeException ex) - { - assertEquals(ex.getMessage(), "Error updating property 'failure' of PropertyUtilsExceptionBean: setFailure"); - } - } - - @Test - public void failure_when_introspecting_class() - { - UglyBean b = new UglyBean(); - - try - { - access.get(b, "google"); - unreachable(); - } catch (RuntimeException ex) - { - assertEquals(ex.getMessage(), "java.lang.RuntimeException: This is the UglyBean."); - } - } - - @Test - public void clear_wipes_internal_cache() - { - ClassPropertyAdapter cpa1 = access.getAdapter(Bean.class); - - assertSame(cpa1.getBeanType(), Bean.class); - - ClassPropertyAdapter cpa2 = access.getAdapter(Bean.class); - - assertSame(cpa2, cpa1); - - access.clearCache(); - - ClassPropertyAdapter cpa3 = access.getAdapter(Bean.class); - - assertNotSame(cpa3, cpa1); - } - - @Test - public void class_property_adapter_toString() - { - ClassPropertyAdapter cpa = access.getAdapter(Bean.class); - - assertEquals(cpa.toString(), "<ClassPropertyAdaptor " + CLASS_NAME - + "$Bean : PI, class, readOnly, value, writeOnly>"); - } - - @Test - public void property_adapter_read_only_property() - { - ClassPropertyAdapter cpa = access.getAdapter(Bean.class); - PropertyAdapter pa = cpa.getPropertyAdapter("readOnly"); - - assertTrue(pa.isRead()); - assertFalse(pa.isUpdate()); - assertFalse(pa.isCastRequired()); - - assertNull(pa.getWriteMethod()); - assertEquals(pa.getReadMethod(), findMethod(Bean.class, "getReadOnly")); - } - - @Test - public void property_adapter_write_only_property() - { - ClassPropertyAdapter cpa = access.getAdapter(Bean.class); - PropertyAdapter pa = cpa.getPropertyAdapter("writeOnly"); - - assertFalse(pa.isRead()); - assertTrue(pa.isUpdate()); - - assertEquals(pa.getWriteMethod(), findMethod(Bean.class, "setWriteOnly")); - assertNull(pa.getReadMethod()); - } - - @Test - public void class_property_adapter_returns_null_for_unknown_property() - { - ClassPropertyAdapter cpa = access.getAdapter(Bean.class); - - assertNull(cpa.getPropertyAdapter("google")); - } - - @Test - public void access_to_property_type() - { - ClassPropertyAdapter cpa = access.getAdapter(Bean.class); - - assertEquals(cpa.getPropertyAdapter("value").getType(), int.class); - assertEquals(cpa.getPropertyAdapter("readOnly").getType(), String.class); - assertEquals(cpa.getPropertyAdapter("writeOnly").getType(), boolean.class); - } - - @Test - public void property_names() - { - ClassPropertyAdapter cpa = access.getAdapter(Bean.class); - - assertEquals(cpa.getPropertyNames(), Arrays.asList("PI", "class", "readOnly", "value", "writeOnly")); - } - - @Test - public void read_static_field() - { - PropertyAdapter adapter = access.getAdapter(Bean.class).getPropertyAdapter("pi"); - - assertSame(adapter.get(null), Bean.PI); - } - - @Test - public void static_final_fields_may_not_be_changed() - { - PropertyAdapter adapter = access.getAdapter(Bean.class).getPropertyAdapter("pi"); - - try - { - adapter.set(null, 3.0d); - unreachable(); - } catch (RuntimeException ex) - { - // The exact text varies from JDK to JDK - assertMessageContains(ex, "final", "PI"); - } - } - - @Test - public void integration() - { - Registry registry = buildRegistry(); - - PropertyAccess pa = registry.getService("PropertyAccess", PropertyAccess.class); - - Bean b = new Bean(); - - int value = random.nextInt(); - - pa.set(b, "value", value); - - assertEquals(b.getValue(), value); - - registry.shutdown(); - } - - @Test - public void super_interface_methods_inherited_by_sub_interface() - { - ClassPropertyAdapter cpa = access.getAdapter(SubInterface.class); - - assertEquals(cpa.getPropertyNames(), Arrays.asList("grandParentProperty", "parentProperty", "subProperty")); - } - - @Test - public void indexed_properties_are_ignored() - { - ClassPropertyAdapter cpa = access.getAdapter(BeanWithIndexedProperty.class); - - assertEquals(cpa.getPropertyNames(), Arrays.asList("class", "primitiveProperty")); - } - - @Test - public void get_annotation_when_annotation_not_present() - { - PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("readWrite"); - - assertNull(pa.getAnnotation(Scope.class)); - } - - @Test - public void get_annotation_with_annotation_on_write_method() - { - PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("annotationOnWrite"); - - Scope annotation = pa.getAnnotation(Scope.class); - assertNotNull(annotation); - - assertEquals(annotation.value(), "onwrite"); - } - - @Test - public void read_method_annotation_overrides_write_method_annotation() - { - PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("annotationOnRead"); - - Scope annotation = pa.getAnnotation(Scope.class); - assertNotNull(annotation); - - assertEquals(annotation.value(), "onread"); - } - - @Test - public void no_write_method_reading_missing_annotation() - { - PropertyAdapter pa = access.getAdapter(AnnotatedBean.class).getPropertyAdapter("readOnly"); - - assertNull(pa.getAnnotation(Scope.class)); - } - - @Test - public void get_annotation_will_read_field() - { - PropertyAdapter pa = access.getAdapter(Bean.class).getPropertyAdapter("value"); - - DataType dt = pa.getAnnotation(DataType.class); - - assertNotNull(dt); - assertEquals(dt.value(), "fred"); - } - - /** - * TAPESTRY-2448 - */ - @Test - public void get_annotation_will_read_inherited_field() - { - PropertyAdapter pa = access.getAdapter(BeanSubclass.class).getPropertyAdapter("value"); - - DataType dt = pa.getAnnotation(DataType.class); - - assertNotNull(dt); - assertEquals(dt.value(), "fred"); - - } - - @Test - public void field_annotation_overridden_by_getter_annotation() - { - PropertyAdapter pa = access.getAdapter(Bean.class).getPropertyAdapter("value"); - - assertEquals(pa.getAnnotation(Validate.class).value(), "getter-value-overrides"); - } - - @Test - public void using_generics() - { - ClassPropertyAdapter cpa1 = access.getAdapter(StringLongPair.class); - - PropertyAdapter pa1 = cpa1.getPropertyAdapter("key"); - assertSame(pa1.getType(), String.class); - assertTrue(pa1.isCastRequired()); - - assertSame(pa1.getDeclaringClass(), Pair.class); - - PropertyAdapter pa2 = cpa1.getPropertyAdapter("value"); - assertSame(pa2.getType(), Long.class); - assertTrue(pa2.isCastRequired()); - - // On the base class, which defines the generic parameter type variables, - // the properties just look like Object. - - ClassPropertyAdapter cpa2 = access.getAdapter(Pair.class); - - pa1 = cpa2.getPropertyAdapter("key"); - assertSame(pa1.getType(), Object.class); - assertFalse(pa1.isCastRequired()); - - pa2 = cpa2.getPropertyAdapter("value"); - assertSame(pa2.getType(), Object.class); - assertFalse(pa2.isCastRequired()); - - } - - @Test - public void get_scala_properties_with_bean_accessors() - { - PropertyAdapter pa = access.getAdapter(ScalaBean.class).getPropertyAdapter("value"); - - // even thought scala accessors are present the java bean ones should be the ones used by Tapestry - assertEquals(pa.getReadMethod().getName(), "getValue"); - assertEquals(pa.getWriteMethod().getName(), "setValue"); - } - - @Test - public void get_scala_properties() - { - PropertyAdapter pa = access.getAdapter(ScalaClass.class).getPropertyAdapter("value"); - - assertEquals(pa.getReadMethod().getName(), "value"); - assertEquals(pa.getWriteMethod().getName(), "value_$eq"); - } - - @Test - public void access_to_public_field() - { - PropertyAdapter pa = access.getAdapter(PublicFieldBean.class).getPropertyAdapter("value"); - - assertTrue(pa.isField()); - assertTrue(pa.isRead()); - assertTrue(pa.isUpdate()); - - PublicFieldBean bean = new PublicFieldBean(); - - pa.set(bean, "fred"); - - assertEquals(bean.value, "fred"); - - bean.value = "barney"; - - assertEquals(pa.get(bean), "barney"); - } - - @Test - public void property_is_favored_over_public_field() - { - PropertyAdapter pa = access.getAdapter(ShadowedPublicFieldBean.class).getPropertyAdapter("value"); - - assertFalse(pa.isField()); - - ShadowedPublicFieldBean bean = new ShadowedPublicFieldBean(); - - pa.set(bean, "fred"); - - assertNull(bean.value); - - bean.value = "barney"; - bean.setValue("wilma"); - - assertEquals(pa.get(bean), "wilma"); - } - - @Test - public void access_property_from_unimplemented_interface_in_abstract_base_class() - { - AbstractBean bean = new ConcreteBean(33); - - PropertyAdapter valueAdapter = access.getAdapter(AbstractBean.class).getPropertyAdapter("value"); - - assertNotNull(valueAdapter); - assertFalse(valueAdapter.isField()); - - valueAdapter.set(bean, "Hello"); - - assertSame(valueAdapter.get(bean), "Hello"); - assertSame(bean.getValue(), "Hello"); - - PropertyAdapter otherValueAdapter = access.getAdapter(AbstractBean.class).getPropertyAdapter("otherValue"); - - assertNotNull(otherValueAdapter); - assertFalse(otherValueAdapter.isField()); - - otherValueAdapter.set(bean, "Other Value"); - - assertSame(otherValueAdapter.get(bean), "Other Value"); - assertSame(bean.getOtherValue(), "Other Value"); - - PropertyAdapter intValueAdapter = access.getAdapter(AbstractBean.class).getPropertyAdapter("intvalue"); - assertNotNull(intValueAdapter); - - assertEquals(intValueAdapter.get(bean), 33); - - assertTrue(intValueAdapter.isRead()); - assertFalse(intValueAdapter.isUpdate()); - } - - - @Test - public void generic_field_is_recognized() - { - PropertyAdapter pa = access.getAdapter(GenericStringBean.class).getPropertyAdapter("value"); - - assertTrue(pa.isCastRequired()); - assertEquals(pa.getType(), String.class); - assertSame(pa.getDeclaringClass(), GenericBean.class); - } -} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PublicFieldBean.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PublicFieldBean.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PublicFieldBean.java new file mode 100644 index 0000000..abb0e3c --- /dev/null +++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/PublicFieldBean.java @@ -0,0 +1,7 @@ +package org.apache.tapestry5.ioc.internal.services; + +public class PublicFieldBean +{ + public String value; + +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ShadowedPublicFieldBean.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ShadowedPublicFieldBean.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ShadowedPublicFieldBean.java new file mode 100644 index 0000000..485806e --- /dev/null +++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/services/ShadowedPublicFieldBean.java @@ -0,0 +1,18 @@ +package org.apache.tapestry5.ioc.internal.services; + +public class ShadowedPublicFieldBean +{ + private String _value; + + public String value; + + public String getValue() + { + return _value; + } + + public void setValue(String value) + { + _value = value; + } +} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java deleted file mode 100644 index 2fd0fa2..0000000 --- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2008 The Apache Software Foundation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package org.apache.tapestry5.ioc.test; - -public class BeanSubclass extends Bean -{ - private boolean flag; - - public boolean isFlag() - { - return flag; - } -} http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/37efe7ef/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java ---------------------------------------------------------------------- diff --git a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java index 54bd9ac..03cec2d 100644 --- a/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java +++ b/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java @@ -1,4 +1,4 @@ -// Copyright 2008 The Apache Software Foundation +// Copyright 2008, 2012 The Apache Software Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,6 +14,7 @@ package org.apache.tapestry5.ioc.test; +import org.apache.tapestry5.ioc.internal.services.BeanSubclass; import org.testng.annotations.Test; public class TestBaseTest extends TestBase
