blob: 560bbdac19586562dde4b7c3c798c4d66f3b30cf [file] [log] [blame]
package groovy.bugs
import org.codehaus.groovy.runtime.InvokerHelper
class CustomMetaClassTest extends GroovyTestCase{
void testReplaceMetaClass() {
/*
* Constructing first instance before meta class replacment
* is made.
*/
def firstInstance = "first"
assertEquals "first", firstInstance.toString()
MetaClassRegistry registry = InvokerHelper.metaRegistry
def stored = registry.getMetaClass(String.class)
assert stored instanceof MetaClassImpl
def myMetaClass = new MyDelegatingMetaClass(String.class)
registry.removeMetaClass String.class
registry.setMetaClass(String.class, myMetaClass)
/*
* Constructing second instance after meta class replacment
* is made.
*/
def secondInstance = "second"
/*
* Since we are replacing a meta class at the class level
* we are changing the behavior of the first and second
* instance of the string.
*/
assertEquals "changed first", firstInstance.toString()
assertEquals "changed second", secondInstance.toString()
registry.removeMetaClass String.class
stored = registry.getMetaClass(String.class)
assert stored instanceof MetaClassImpl
}
void testNormalCreated () {
assertEquals groovy.runtime.metaclass.groovy.bugs.CustomMetaClassTestMetaClass, metaClass.class
assertEquals MetaClassImpl, metaClass.delegate.class
}
void testEmcCreated () {
GroovySystem.metaClassRegistry.removeMetaClass metaClass.theClass
ExpandoMetaClass.enableGlobally()
metaClass = GroovySystem.metaClassRegistry.getMetaClass(CustomMetaClassTest)
assertTrue metaClass instanceof groovy.runtime.metaclass.groovy.bugs.CustomMetaClassTestMetaClass
assertEquals ExpandoMetaClass, metaClass.delegate.class
ExpandoMetaClass.disableGlobally()
GroovySystem.metaClassRegistry.removeMetaClass metaClass.theClass
metaClass = null
assert getMetaClass() instanceof groovy.runtime.metaclass.groovy.bugs.CustomMetaClassTestMetaClass
assert MetaClassImpl == getMetaClass().delegate.class
}
void testStaticMetaClass () {
// Custom metaclass created
assertEquals groovy.runtime.metaclass.groovy.bugs.CustomMetaClassTestMetaClass, metaClass.class
// delegated to MCImpl
assertEquals MetaClassImpl, metaClass.delegate.class
MetaClass expandoMetaClass = CustomMetaClassTest.metaClass
// It still to be custom
assertEquals groovy.runtime.metaclass.groovy.bugs.CustomMetaClassTestMetaClass, expandoMetaClass.class
// But delegated to EMC
assertEquals ExpandoMetaClass, expandoMetaClass.delegate.class
// But object still to hold reference to old one
assertEquals MetaClassImpl, metaClass.delegate.class
// let give it chance to reinitialize
metaClass = null
// Now it should be OK
assertEquals ExpandoMetaClass, expandoMetaClass.delegate.class
expandoMetaClass.toString = {
-> "I am modified"
}
assertEquals "I am modified", toString()
assertEquals "I am modified", metaClass.invokeMethod(this, "toString", null)
expandoMetaClass.static.toString = {
-> "I am modified static"
}
assertEquals "I am modified static", getClass().toString()
GroovySystem.metaClassRegistry.removeMetaClass metaClass.theClass
metaClass = null
assert getMetaClass() instanceof groovy.runtime.metaclass.groovy.bugs.CustomMetaClassTestMetaClass
assert MetaClassImpl == getMetaClass().delegate.class
}
}
class MyDelegatingMetaClass extends groovy.lang.DelegatingMetaClass
{
MyDelegatingMetaClass(final Class a_class)
{
super(a_class);
initialize()
}
public Object invokeMethod(Object a_object, String a_methodName, Object[] a_arguments)
{
return "changed ${super.invokeMethod(a_object, a_methodName, a_arguments)}"
}
}