1 package org.hamcrest.beans; 2 3 import org.hamcrest.AbstractMatcherTest; 4 import org.hamcrest.Description; 5 import org.hamcrest.Matcher; 6 import org.hamcrest.StringDescription; 7 import org.hamcrest.core.IsEqual; 8 9 import java.beans.IntrospectionException; 10 import java.beans.PropertyDescriptor; 11 import java.beans.SimpleBeanInfo; 12 13 import static org.hamcrest.MatcherAssert.assertThat; 14 import static org.hamcrest.beans.HasPropertyWithValue.hasProperty; 15 import static org.hamcrest.core.IsAnything.anything; 16 import static org.hamcrest.core.IsEqual.equalTo; 17 18 /** 19 * @author Iain McGinniss 20 * @author Nat Pryce 21 * @author Steve Freeman 22 * @since 1.1.0 23 */ 24 @SuppressWarnings("UnusedDeclaration") 25 public class HasPropertyWithValueTest extends AbstractMatcherTest { 26 private final BeanWithoutInfo shouldMatch = new BeanWithoutInfo("is expected"); 27 private final BeanWithoutInfo shouldNotMatch = new BeanWithoutInfo("not expected"); 28 29 private final BeanWithInfo beanWithInfo = new BeanWithInfo("with info"); 30 31 @Override createMatcher()32 protected Matcher<?> createMatcher() { 33 return hasProperty("irrelevant", anything()); 34 } 35 testMatchesInfolessBeanWithMatchedNamedProperty()36 public void testMatchesInfolessBeanWithMatchedNamedProperty() { 37 assertMatches("with property", hasProperty("property", equalTo("is expected")), shouldMatch); 38 assertMismatchDescription("property 'property' was \"not expected\"", 39 hasProperty("property", equalTo("is expected")), shouldNotMatch); 40 } 41 testMatchesBeanWithInfoWithMatchedNamedProperty()42 public void testMatchesBeanWithInfoWithMatchedNamedProperty() { 43 assertMatches("with bean info", hasProperty("property", equalTo("with info")), beanWithInfo); 44 assertMismatchDescription("property 'property' was \"with info\"", 45 hasProperty("property", equalTo("without info")), beanWithInfo); 46 } 47 testDoesNotMatchInfolessBeanWithoutMatchedNamedProperty()48 public void testDoesNotMatchInfolessBeanWithoutMatchedNamedProperty() { 49 assertMismatchDescription("No property \"nonExistentProperty\"", 50 hasProperty("nonExistentProperty", anything()), shouldNotMatch); 51 } 52 testDoesNotMatchWriteOnlyProperty()53 public void testDoesNotMatchWriteOnlyProperty() { 54 assertMismatchDescription("property \"writeOnlyProperty\" is not readable", 55 hasProperty("writeOnlyProperty", anything()), shouldNotMatch); 56 } 57 testDescribeTo()58 public void testDescribeTo() { 59 assertDescription("hasProperty(\"property\", <true>)", hasProperty("property", equalTo(true))); 60 } 61 testMatchesPropertyAndValue()62 public void testMatchesPropertyAndValue() { 63 assertMatches("property with value", hasProperty( "property", anything()), beanWithInfo); 64 } 65 testDoesNotWriteMismatchIfPropertyMatches()66 public void testDoesNotWriteMismatchIfPropertyMatches() { 67 Description description = new StringDescription(); 68 hasProperty( "property", anything()).describeMismatch(beanWithInfo, description); 69 assertEquals("Expected mismatch description", "", description.toString()); 70 } 71 testDescribesMissingPropertyMismatch()72 public void testDescribesMissingPropertyMismatch() { 73 assertMismatchDescription("No property \"honk\"", hasProperty( "honk", anything()), shouldNotMatch); 74 } 75 testCanAccessAnAnonymousInnerClass()76 public void testCanAccessAnAnonymousInnerClass() { 77 class X implements IX { 78 @Override 79 public int getTest() { 80 return 1; 81 } 82 } 83 84 assertThat(new X(), HasPropertyWithValue.hasProperty("test", IsEqual.equalTo(1))); 85 } 86 87 interface IX { getTest()88 int getTest(); 89 } 90 91 public static class BeanWithoutInfo { 92 private String property; 93 BeanWithoutInfo(String property)94 public BeanWithoutInfo(String property) { 95 this.property = property; 96 } 97 getProperty()98 public String getProperty() { 99 return property; 100 } 101 setProperty(String property)102 public void setProperty(String property) { 103 this.property = property; 104 } 105 setWriteOnlyProperty(@uppressWarnings"unused") float property)106 public void setWriteOnlyProperty(@SuppressWarnings("unused") float property) { 107 } 108 109 @Override toString()110 public String toString() { 111 return "[Person: " + property + "]"; 112 } 113 } 114 115 public static class BeanWithInfo { 116 private final String propertyValue; 117 BeanWithInfo(String propertyValue)118 public BeanWithInfo(String propertyValue) { 119 this.propertyValue = propertyValue; 120 } 121 property()122 public String property() { 123 return propertyValue; 124 } 125 } 126 127 public static class BeanWithInfoBeanInfo extends SimpleBeanInfo { 128 @Override getPropertyDescriptors()129 public PropertyDescriptor[] getPropertyDescriptors() { 130 try { 131 return new PropertyDescriptor[] { 132 new PropertyDescriptor("property", BeanWithInfo.class, "property", null) 133 }; 134 } catch (IntrospectionException e) { 135 throw new RuntimeException("Introspection exception: " + e.getMessage()); 136 } 137 } 138 } 139 } 140