org.gradle.api.internal.ExtensibleDynamicObjectTest Maven / Gradle / Ivy
/*
* Copyright 2008 the original author or authors.
*
* 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.gradle.api.internal;
import groovy.lang.*;
import groovy.lang.MissingMethodException;
import org.gradle.api.plugins.Convention;
import org.gradle.internal.metaobject.BeanDynamicObject;
import org.gradle.internal.metaobject.DynamicObject;
import org.gradle.util.TestUtil;
import org.junit.Test;
import java.util.Map;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class ExtensibleDynamicObjectTest {
@Test
public void hasPropertiesDefinedByClass() {
Bean bean = new Bean();
assertTrue(bean.hasProperty("readWriteProperty"));
assertTrue(bean.hasProperty("readOnlyProperty"));
assertTrue(bean.hasProperty("writeOnlyProperty"));
}
@Test
public void canGetAndSetClassProperty() {
Bean bean = new Bean();
bean.setReadWriteProperty("value");
assertThat(bean.getProperty("readWriteProperty"), equalTo((Object) "value"));
bean.setProperty("readWriteProperty", "new value");
assertThat(bean.getProperty("readWriteProperty"), equalTo((Object) "new value"));
assertThat(bean.getReadWriteProperty(), equalTo((Object) "new value"));
}
@Test
public void canGetReadOnlyClassProperty() {
Bean bean = new Bean();
bean.doSetReadOnlyProperty("value");
assertThat(bean.getProperty("readOnlyProperty"), equalTo((Object) "value"));
}
@Test
public void cannotSetReadOnlyClassProperty() {
Bean bean = new Bean();
try {
bean.setProperty("readOnlyProperty", "value");
fail();
} catch (GroovyRuntimeException e) {
assertThat(e.getMessage(), equalTo("Cannot set the value of read-only property 'readOnlyProperty' for of type " + Bean.class.getName() + "."));
}
}
@Test
public void canSetWriteOnlyClassProperty() {
Bean bean = new Bean();
bean.setProperty("writeOnlyProperty", "value");
assertThat(bean.doGetWriteOnlyProperty(), equalTo("value"));
}
@Test
public void cannotGetWriteOnlyClassProperty() {
Bean bean = new Bean();
try {
bean.getProperty("writeOnlyProperty");
fail();
} catch (GroovyRuntimeException e) {
assertThat(e.getMessage(), equalTo("Cannot get the value of write-only property 'writeOnlyProperty' for of type " + Bean.class.getName() + "."));
}
}
@Test
public void canSetPropertyWhenGetterAndSetterHaveDifferentTypes() {
Bean bean = new Bean();
bean.setProperty("differentTypesProperty", "91");
assertThat(bean.getProperty("differentTypesProperty"), equalTo((Object) 91));
}
@Test
public void groovyObjectHasPropertiesDefinedByClassMetaInfo() {
GroovyBean bean = new GroovyBean();
ExtensibleDynamicObjectTestHelper.decorateGroovyBean(bean);
assertTrue(bean.hasProperty("groovyProperty"));
assertTrue(bean.hasProperty("dynamicGroovyProperty"));
}
@Test
public void groovyObjectHasPropertiesInheritedFromSuperClass() {
GroovyBean bean = new GroovyBean();
assertTrue(bean.hasProperty("readWriteProperty"));
assertTrue(bean.hasProperty("readOnlyProperty"));
assertTrue(bean.hasProperty("writeOnlyProperty"));
}
@Test
public void canGetAndSetGroovyObjectClassProperty() {
GroovyBean bean = new GroovyBean();
bean.setGroovyProperty("value");
assertThat(((Bean) bean).getProperty("groovyProperty"), equalTo((Object) "value"));
bean.setProperty("groovyProperty", "new value");
assertThat(((Bean) bean).getProperty("groovyProperty"), equalTo((Object) "new value"));
assertThat(bean.getGroovyProperty(), equalTo((Object) "new value"));
}
@Test
public void canGetAndSetGroovyDynamicProperty() {
GroovyBean bean = new GroovyBean();
ExtensibleDynamicObjectTestHelper.decorateGroovyBean(bean);
assertThat(((Bean) bean).getProperty("dynamicGroovyProperty"), equalTo(null));
bean.setProperty("dynamicGroovyProperty", "new value");
assertThat(((Bean) bean).getProperty("dynamicGroovyProperty"), equalTo((Object) "new value"));
}
@Test
public void canGetButNotSetPropertiesOnJavaObjectFromGroovy() {
ExtensibleDynamicObjectTestHelper.assertCanGetProperties(new Bean());
}
@Test
public void canGetAndSetPropertiesOnGroovyObjectFromGroovy() {
ExtensibleDynamicObjectTestHelper.assertCanGetAndSetProperties(new GroovyBean());
}
@Test
public void canGetAndSetPropertiesOnGroovyObjectFromJava() {
assertCanGetAndSetProperties(new GroovyBean().getAsDynamicObject());
}
@Test
public void canGetAndSetPropertiesOnJavaSubClassOfGroovyObjectFromJava() {
assertCanGetAndSetProperties(new DynamicJavaBean().getAsDynamicObject());
}
private void assertCanGetAndSetProperties(DynamicObject bean) {
bean.setProperty("readWriteProperty", "value");
assertThat(bean.getProperty("readWriteProperty"), equalTo((Object) "value"));
bean.setProperty("groovyProperty", "value");
assertThat(bean.getProperty("groovyProperty"), equalTo((Object) "value"));
}
@Test
public void canGetAndSetPropertiesOnJavaSubClassOfGroovyObjectFromGroovy() {
ExtensibleDynamicObjectTestHelper.assertCanGetAndSetProperties(new DynamicJavaBean());
}
@Test
public void hasPropertyDefinedByConventionObject() {
Bean bean = new Bean();
Convention convention = bean.extensibleDynamicObject.getConvention();
assertFalse(bean.hasProperty("conventionProperty"));
assertFalse(bean.hasProperty("conventionProperty"));
convention.getPlugins().put("test", new ConventionBean());
assertTrue(bean.hasProperty("conventionProperty"));
}
@Test
public void canGetAndSetPropertyDefinedByConventionObject() {
Bean bean = new Bean();
Convention convention = bean.extensibleDynamicObject.getConvention();
ConventionBean conventionBean = new ConventionBean();
convention.getPlugins().put("test", conventionBean);
conventionBean.setConventionProperty("value");
assertThat(bean.getProperty("conventionProperty"), equalTo((Object) "value"));
bean.setProperty("conventionProperty", "new value");
assertThat(bean.getProperty("conventionProperty"), equalTo((Object) "new value"));
assertThat(conventionBean.getConventionProperty(), equalTo((Object) "new value"));
}
@Test
public void hasPropertyDefinedByParent() {
Bean parent = new Bean();
parent.defineProperty("parentProperty", "value");
Bean bean = new Bean();
assertFalse(bean.hasProperty("parentProperty"));
bean.setParent(parent.getAsDynamicObject());
assertTrue(bean.hasProperty("parentProperty"));
}
@Test
public void canGetPropertyDefinedByParent() {
Bean parent = new Bean();
parent.defineProperty("parentProperty", "value");
Bean bean = new Bean();
bean.setParent(parent.getAsDynamicObject());
assertThat(bean.getProperty("parentProperty"), equalTo((Object) "value"));
}
@Test
public void extraPropertyIsNotVisibleToParent() {
Bean parent = new Bean();
Bean bean = new Bean();
bean.setParent(parent.getAsDynamicObject());
bean.defineProperty("parentProperty", "value");
assertFalse(parent.hasProperty("parentProperty"));
}
@Test
public void hasAdditionalProperty() {
Bean bean = new Bean();
assertFalse(bean.hasProperty("additional"));
bean.defineProperty("additional", "value");
assertTrue(bean.hasProperty("additional"));
bean.setProperty("additional", null);
assertTrue(bean.hasProperty("additional"));
}
@Test
public void canGetAndSetExtraProperty() {
Bean bean = new Bean();
bean.defineProperty("additional", "value 1");
assertThat(bean.getProperty("additional"), equalTo((Object) "value 1"));
bean.setProperty("additional", "value 2");
assertThat(bean.getProperty("additional"), equalTo((Object) "value 2"));
}
@Test
public void canGetAndSetPropertyDefinedByAdditionalObject() {
Bean otherObject = new Bean();
otherObject.defineProperty("otherObject", "value");
Bean bean = new Bean();
bean.extensibleDynamicObject.addObject(otherObject.getAsDynamicObject(), ExtensibleDynamicObject.Location.BeforeConvention);
assertTrue(bean.hasProperty("otherObject"));
assertThat(bean.getProperty("otherObject"), equalTo((Object) "value"));
bean.setProperty("otherObject", "new value");
assertThat(otherObject.getProperty("otherObject"), equalTo((Object) "new value"));
}
@Test
public void classPropertyTakesPrecedenceOverAdditionalProperty() {
Bean bean = new Bean();
bean.setReadWriteProperty("value");
bean.extensibleDynamicObject.getDynamicProperties().set("readWriteProperty", "additional");
assertThat(bean.getProperty("readWriteProperty"), equalTo((Object) "value"));
bean.setProperty("readWriteProperty", "new value");
assertThat(bean.getProperty("readWriteProperty"), equalTo((Object) "new value"));
assertThat(bean.getReadWriteProperty(), equalTo((Object) "new value"));
assertThat(bean.extensibleDynamicObject.getDynamicProperties().get("readWriteProperty"), equalTo((Object) "additional"));
}
@Test
public void extraPropertyTakesPrecedenceOverConventionProperty() {
Bean bean = new Bean();
bean.defineProperty("conventionProperty", "value");
Convention convention = bean.extensibleDynamicObject.getConvention();
ConventionBean conventionBean = new ConventionBean();
convention.getPlugins().put("test", conventionBean);
assertThat(bean.getProperty("conventionProperty"), equalTo((Object) "value"));
bean.setProperty("conventionProperty", "new value");
assertThat(bean.getProperty("conventionProperty"), equalTo((Object) "new value"));
assertThat(bean.extensibleDynamicObject.getDynamicProperties().get("conventionProperty"), equalTo((Object) "new value"));
assertThat(conventionBean.getConventionProperty(), nullValue());
}
@Test
public void conventionPropertyTakesPrecedenceOverParentProperty() {
Bean parent = new Bean();
parent.defineProperty("conventionProperty", "parent");
Bean bean = new Bean();
bean.setParent(parent.getAsDynamicObject());
Convention convention = bean.extensibleDynamicObject.getConvention();
ConventionBean conventionBean = new ConventionBean();
conventionBean.setConventionProperty("value");
convention.getPlugins().put("test", conventionBean);
assertThat(bean.getProperty("conventionProperty"), equalTo((Object) "value"));
}
@Test
public void canGetAllProperties() {
Bean parent = new Bean();
parent.defineProperty("parentProperty", "parentProperty");
parent.setReadWriteProperty("ignore me");
parent.doSetReadOnlyProperty("ignore me");
Convention parentConvention = parent.extensibleDynamicObject.getConvention();
parentConvention.getPlugins().put("parent", new ConventionBean());
GroovyBean bean = new GroovyBean();
bean.defineProperty("additional", "additional");
bean.setReadWriteProperty("readWriteProperty");
bean.doSetReadOnlyProperty("readOnlyProperty");
bean.setGroovyProperty("groovyProperty");
Convention convention = bean.extensibleDynamicObject.getConvention();
ConventionBean conventionBean = new ConventionBean();
conventionBean.setConventionProperty("conventionProperty");
convention.getPlugins().put("bean", conventionBean);
bean.setParent(parent.getAsDynamicObject());
Map properties = bean.getProperties();
assertThat(properties.get("properties"), sameInstance((Object) properties));
assertThat(properties.get("readWriteProperty"), equalTo((Object) "readWriteProperty"));
assertThat(properties.get("readOnlyProperty"), equalTo((Object) "readOnlyProperty"));
assertThat(properties.get("parentProperty"), equalTo((Object) "parentProperty"));
assertThat(properties.get("additional"), equalTo((Object) "additional"));
assertThat(properties.get("groovyProperty"), equalTo((Object) "groovyProperty"));
assertThat(properties.get("groovyDynamicProperty"), equalTo(null));
assertThat(properties.get("conventionProperty"), equalTo((Object) "conventionProperty"));
}
@Test
public void canGetAllPropertiesFromGroovy() {
ExtensibleDynamicObjectTestHelper.assertCanGetAllProperties(new Bean());
ExtensibleDynamicObjectTestHelper.assertCanGetAllProperties(new GroovyBean());
ExtensibleDynamicObjectTestHelper.assertCanGetAllProperties(new DynamicJavaBean());
}
@Test
public void getPropertyFailsForUnknownProperty() {
Bean bean = new Bean();
try {
bean.getProperty("unknown");
fail();
} catch (MissingPropertyException e) {
assertThat(e.getMessage(), equalTo("Could not get unknown property 'unknown' for of type " + Bean.class.getName() + "."));
}
bean.setParent(new Bean() {
@Override
public String toString() {
return "";
}
}.getAsDynamicObject());
try {
bean.getProperty("unknown");
fail();
} catch (MissingPropertyException e) {
assertThat(e.getMessage(), equalTo("Could not get unknown property 'unknown' for of type " + Bean.class.getName() + "."));
}
}
@Test
public void doesNotIncludeToStringInGetPropertyErrorMessageWhenItIsNotImplemented() {
DynamicObject bean = new ExtensibleDynamicObject(new Object(), Object.class, ThreadGlobalInstantiator.getOrCreate());
try {
bean.getProperty("unknown");
fail();
} catch (MissingPropertyException e) {
assertThat(e.getMessage(), equalTo("Could not get unknown property 'unknown' for object of type java.lang.Object."));
}
}
@Test
public void setPropertyFailsForUnknownProperty() {
Bean bean = new Bean();
try {
bean.setProperty("unknown", 12);
fail();
} catch (MissingPropertyException e) {
assertThat(e.getMessage(), equalTo("Could not set unknown property 'unknown' for of type " + Bean.class.getName() + "."));
}
}
@Test
public void doesNotIncludeToStringInSetPropertyErrorMessageWhenItIsNotImplemented() {
DynamicObject bean = new ExtensibleDynamicObject(new Object(), Object.class, ThreadGlobalInstantiator.getOrCreate());
try {
bean.setProperty("unknown", "value");
fail();
} catch (MissingPropertyException e) {
assertThat(e.getMessage(), equalTo("Could not set unknown property 'unknown' for object of type java.lang.Object."));
}
}
@Test
public void extraPropertyWithNullValueIsNotTreatedAsUnknown() {
Bean bean = new Bean();
bean.defineProperty("additional", null);
assertThat(bean.getProperty("additional"), nullValue());
}
@Test
public void canInvokeMethodDefinedByClass() {
Bean bean = new Bean();
assertTrue(bean.hasMethod("javaMethod", "a", "b"));
assertThat(bean.getAsDynamicObject().invokeMethod("javaMethod", "a", "b"), equalTo((Object) "java:a.b"));
}
@Test
public void canInvokeMethodDefinedByMetaClass() {
Bean bean = new GroovyBean();
ExtensibleDynamicObjectTestHelper.decorateGroovyBean(bean);
assertTrue(bean.hasMethod("groovyMethod", "a", "b"));
assertThat(bean.getAsDynamicObject().invokeMethod("groovyMethod", "a", "b"), equalTo((Object) "groovy:a.b"));
assertTrue(bean.hasMethod("dynamicGroovyMethod", "a", "b"));
assertThat(bean.getAsDynamicObject().invokeMethod("dynamicGroovyMethod", "a", "b"), equalTo((Object) "dynamicGroovy:a.b"));
}
@Test
public void canInvokeMethodDefinedByScriptObject() {
Bean bean = new Bean();
Script script = TestUtil.createScript("def scriptMethod(a, b) { \"script:$a.$b\" } ");
bean.extensibleDynamicObject.addObject(new BeanDynamicObject(script), ExtensibleDynamicObject.Location.BeforeConvention);
assertTrue(bean.hasMethod("scriptMethod", "a", "b"));
assertThat(bean.getAsDynamicObject().invokeMethod("scriptMethod", "a", "b").toString(), equalTo((Object) "script:a.b"));
}
@Test
public void canInvokeMethodDefinedByConvention() {
Bean bean = new Bean();
Convention convention = bean.extensibleDynamicObject.getConvention();
assertFalse(bean.hasMethod("conventionMethod", "a", "b"));
convention.getPlugins().put("bean", new ConventionBean());
assertTrue(bean.hasMethod("conventionMethod", "a", "b"));
assertThat(bean.getAsDynamicObject().invokeMethod("conventionMethod", "a", "b"), equalTo((Object) "convention:a.b"));
}
@Test
public void canInvokeMethodDefinedByParent() {
Bean parent = new Bean() {
public String parentMethod(String a, String b) {
return String.format("parent:%s.%s", a, b);
}
};
Bean bean = new Bean();
assertFalse(bean.hasMethod("parentMethod", "a", "b"));
bean.setParent(parent.getAsDynamicObject());
assertTrue(bean.hasMethod("parentMethod", "a", "b"));
assertThat(bean.getAsDynamicObject().invokeMethod("parentMethod", "a", "b"), equalTo((Object) "parent:a.b"));
}
@Test
public void canInvokeMethodsOnJavaObjectFromGroovy() {
Bean bean = new Bean();
Convention convention = bean.extensibleDynamicObject.getConvention();
convention.getPlugins().put("bean", new ConventionBean());
new ExtensibleDynamicObjectTestHelper().assertCanCallMethods(bean);
}
@Test
public void canInvokeMethodsOnGroovyObjectFromGroovy() {
GroovyBean bean = new GroovyBean();
Convention convention = bean.extensibleDynamicObject.getConvention();
convention.getPlugins().put("bean", new ConventionBean());
new ExtensibleDynamicObjectTestHelper().assertCanCallMethods(bean);
}
@Test
public void canInvokeMethodsOnJavaSubClassOfGroovyObjectFromGroovy() {
// This doesn't work.
// It used to because at the bottom of the hierarchy chain the object implemented methodMissing().
// However, our normal “decorated” classes do not do this so it is not realistic.
// Groovy does something very strange here.
// For some reason (probably because the class is Java), it won't employ any dynamism.
// Even implementing invokeMethod at the Java level has no effect.
DynamicJavaBean javaBean = new DynamicJavaBean();
Convention convention = javaBean.extensibleDynamicObject.getConvention();
convention.getPlugins().put("bean", new ConventionBean());
new ExtensibleDynamicObjectTestHelper().assertCanCallMethods(javaBean);
}
@Test
public void canInvokeClosurePropertyAsAMethod() {
Bean bean = new Bean();
bean.defineProperty("someMethod", TestUtil.toClosure("{ param -> param.toLowerCase() }"));
assertThat(bean.invokeMethod("someMethod", "Param"), equalTo((Object) "param"));
}
@Test
public void invokeMethodFailsForUnknownMethod() {
Bean bean = new Bean();
try {
bean.getAsDynamicObject().invokeMethod("unknown", "a", 12);
fail();
} catch (MissingMethodException e) {
assertThat(e.getMessage(), equalTo("Could not find method unknown() for arguments [a, 12] on of type " + Bean.class.getName() + "."));
}
}
@Test
public void propagatesGetPropertyException() {
final RuntimeException failure = new RuntimeException();
Bean bean = new Bean() {
String getFailure() {
throw failure;
}
};
try {
bean.getProperty("failure");
fail();
} catch (Exception e) {
assertThat(e, sameInstance((Exception) failure));
}
}
@Test
public void propagatesSetPropertyException() {
final RuntimeException failure = new RuntimeException();
Bean bean = new Bean() {
void setFailure(String value) {
throw failure;
}
};
try {
bean.setProperty("failure", "a");
fail();
} catch (Exception e) {
assertThat(e, sameInstance((Exception) failure));
}
}
@Test
public void propagatesInvokeMethodException() {
final RuntimeException failure = new RuntimeException();
Bean bean = new Bean() {
void failure() {
throw failure;
}
};
try {
bean.getAsDynamicObject().invokeMethod("failure");
fail();
} catch (Exception e) {
assertThat(e, sameInstance((Exception) failure));
}
}
@Test
public void extraPropertiesAreInherited() {
Bean bean = new Bean();
bean.defineProperty("additional", "value");
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasProperty("additional"));
assertThat(inherited.getProperty("additional"), equalTo((Object) "value"));
assertThat(inherited.getProperties().get("additional"), equalTo((Object) "value"));
}
@Test
public void inheritedAdditionalPropertiesTrackChanges() {
Bean bean = new Bean();
DynamicObject inherited = bean.getInheritable();
assertFalse(inherited.hasProperty("additional"));
bean.defineProperty("additional", "value");
assertTrue(inherited.hasProperty("additional"));
assertThat(inherited.getProperty("additional"), equalTo((Object) "value"));
}
@Test
public void additionalObjectPropertiesAreInherited() {
Bean other = new Bean();
other.defineProperty("other", "value");
Bean bean = new Bean();
bean.extensibleDynamicObject.addObject(other.getAsDynamicObject(), ExtensibleDynamicObject.Location.BeforeConvention);
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasProperty("other"));
assertThat(inherited.getProperty("other"), equalTo((Object) "value"));
assertThat(inherited.getProperties().get("other"), equalTo((Object) "value"));
}
@Test
public void inheritedAdditionalObjectPropertiesTrackChanges() {
Bean other = new Bean();
other.defineProperty("other", "value");
Bean bean = new Bean();
DynamicObject inherited = bean.getInheritable();
assertFalse(inherited.hasProperty("other"));
bean.extensibleDynamicObject.addObject(other.getAsDynamicObject(), ExtensibleDynamicObject.Location.BeforeConvention);
assertTrue(inherited.hasProperty("other"));
assertThat(inherited.getProperty("other"), equalTo((Object) "value"));
}
@Test
public void conventionPropertiesAreInherited() {
Bean bean = new Bean();
Convention convention = bean.extensibleDynamicObject.getConvention();
ConventionBean conventionBean = new ConventionBean();
conventionBean.setConventionProperty("value");
convention.getPlugins().put("convention", conventionBean);
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasProperty("conventionProperty"));
assertThat(inherited.getProperty("conventionProperty"), equalTo((Object) "value"));
assertThat(inherited.getProperties().get("conventionProperty"), equalTo((Object) "value"));
}
@Test
public void inheritedConventionPropertiesTrackChanges() {
Bean bean = new Bean();
DynamicObject inherited = bean.getInheritable();
assertFalse(inherited.hasProperty("conventionProperty"));
Convention convention = bean.extensibleDynamicObject.getConvention();
ConventionBean conventionBean = new ConventionBean();
conventionBean.setConventionProperty("value");
convention.getPlugins().put("convention", conventionBean);
assertTrue(inherited.hasProperty("conventionProperty"));
assertThat(inherited.getProperty("conventionProperty"), equalTo((Object) "value"));
}
@Test
public void parentPropertiesAreInherited() {
Bean parent = new Bean();
parent.defineProperty("parentProperty", "value");
Bean bean = new Bean();
bean.setParent(parent.getAsDynamicObject());
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasProperty("parentProperty"));
assertThat(inherited.getProperty("parentProperty"), equalTo((Object) "value"));
assertThat(inherited.getProperties().get("parentProperty"), equalTo((Object) "value"));
}
@Test
public void otherPropertiesAreNotInherited() {
Bean bean = new Bean();
assertTrue(bean.hasProperty("readWriteProperty"));
DynamicObject inherited = bean.getInheritable();
assertFalse(inherited.hasProperty("readWriteProperty"));
assertFalse(inherited.getProperties().containsKey("readWriteProperty"));
}
@Test
public void cannotSetInheritedProperties() {
Bean bean = new Bean();
bean.defineProperty("additional", "value");
DynamicObject inherited = bean.getInheritable();
try {
inherited.setProperty("additional", "new value");
fail();
} catch (MissingPropertyException e) {
assertThat(e.getMessage(), equalTo("Could not find property 'additional' inherited from ."));
}
}
@Test
public void conventionMethodsAreInherited() {
Bean bean = new Bean();
Convention convention = bean.extensibleDynamicObject.getConvention();
convention.getPlugins().put("convention", new ConventionBean());
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasMethod("conventionMethod", "a", "b"));
assertThat(inherited.invokeMethod("conventionMethod", "a", "b"), equalTo((Object) "convention:a.b"));
}
@Test
public void additionalObjectMethodsAreInherited() {
Bean other = new Bean();
Convention convention = other.extensibleDynamicObject.getConvention();
convention.getPlugins().put("convention", new ConventionBean());
Bean bean = new Bean();
bean.extensibleDynamicObject.addObject(other.getAsDynamicObject(), ExtensibleDynamicObject.Location.BeforeConvention);
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasMethod("conventionMethod", "a", "b"));
assertThat(inherited.invokeMethod("conventionMethod", "a", "b"), equalTo((Object) "convention:a.b"));
}
@Test
public void parentMethodsAreInherited() {
Bean parent = new Bean();
Convention convention = parent.extensibleDynamicObject.getConvention();
convention.getPlugins().put("convention", new ConventionBean());
Bean bean = new Bean();
bean.setParent(parent.getAsDynamicObject());
DynamicObject inherited = bean.getInheritable();
assertTrue(inherited.hasMethod("conventionMethod", "a", "b"));
assertThat(inherited.invokeMethod("conventionMethod", "a", "b"), equalTo((Object) "convention:a.b"));
}
@Test
public void otherMethodsAreNotInherited() {
Bean bean = new Bean();
assertTrue(bean.hasMethod("javaMethod", "a", "b"));
DynamicObject inherited = bean.getInheritable();
assertFalse(inherited.hasMethod("javaMethod", "a", "b"));
}
@Test
public void canGetObjectAsDynamicObject() {
Bean bean = new Bean();
assertThat(DynamicObjectUtil.asDynamicObject(bean), sameInstance(bean.getAsDynamicObject()));
assertThat(DynamicObjectUtil.asDynamicObject(new Object()), instanceOf(DynamicObject.class));
}
@Test
public void canCallGroovyDynamicMethods() {
DynamicGroovyBean bean = new DynamicGroovyBean();
DynamicObject object = new ExtensibleDynamicObject(bean, DynamicGroovyBean.class, ThreadGlobalInstantiator.getOrCreate());
Integer doubled = (Integer) object.invokeMethod("bar", 1);
assertThat(doubled, equalTo(2));
try {
object.invokeMethod("xxx", 1, 2, 3);
fail();
} catch (MissingMethodException e) {
assertThat(e.getMessage(), equalTo("Could not find method xxx() for arguments [1, 2, 3] on object of type " + DynamicGroovyBean.class.getName() + "."));
}
}
public static class Bean extends GroovyObjectSupport implements DynamicObjectAware {
private String readWriteProperty;
private String _readOnlyProperty;
private String writeOnlyProperty;
private Integer differentTypesProperty;
final ExtensibleDynamicObject extensibleDynamicObject;
public Bean() {
extensibleDynamicObject = new ExtensibleDynamicObject(this, Bean.class, ThreadGlobalInstantiator.getOrCreate());
}
public DynamicObject getAsDynamicObject() {
return extensibleDynamicObject;
}
@Override
public String toString() {
return "";
}
public void setParent(DynamicObject parent) {
extensibleDynamicObject.setParent(parent);
}
public String getReadOnlyProperty() {
return _readOnlyProperty;
}
public void doSetReadOnlyProperty(String readOnlyProperty) {
this._readOnlyProperty = readOnlyProperty;
}
public String doGetWriteOnlyProperty() {
return writeOnlyProperty;
}
public void setWriteOnlyProperty(String writeOnlyProperty) {
this.writeOnlyProperty = writeOnlyProperty;
}
public String getReadWriteProperty() {
return readWriteProperty;
}
public void setReadWriteProperty(String property) {
this.readWriteProperty = property;
}
public Integer getDifferentTypesProperty() {
return differentTypesProperty;
}
public void setDifferentTypesProperty(Object differentTypesProperty) {
this.differentTypesProperty = Integer.parseInt(differentTypesProperty.toString());
}
public String javaMethod(String a, String b) {
return String.format("java:%s.%s", a, b);
}
public Object getProperty(String name) {
return extensibleDynamicObject.getProperty(name);
}
public boolean hasProperty(String name) {
return extensibleDynamicObject.hasProperty(name);
}
public void setProperty(String name, Object value) {
extensibleDynamicObject.setProperty(name, value);
}
public Map getProperties() {
return extensibleDynamicObject.getProperties();
}
public boolean hasMethod(String name, Object... arguments) {
return extensibleDynamicObject.hasMethod(name, arguments);
}
public Object invokeMethod(String name, Object args) {
return extensibleDynamicObject.invokeMethod(name, (args instanceof Object[]) ? (Object[]) args : new Object[]{args});
}
public DynamicObject getInheritable() {
return extensibleDynamicObject.getInheritable();
}
public void defineProperty(String name, Object value) {
extensibleDynamicObject.getConvention().getExtraProperties().set(name, value);
}
}
private static class DynamicJavaBean extends GroovyBean {
}
private static class ConventionBean {
private String conventionProperty;
public String getConventionProperty() {
return conventionProperty;
}
public void setConventionProperty(String conventionProperty) {
this.conventionProperty = conventionProperty;
}
public String conventionMethod(String a, String b) {
return String.format("convention:%s.%s", a, b);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy