You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/11/21 01:05:19 UTC

svn commit: r477421 [2/2] - in /tapestry/tapestry5/tapestry-core/trunk: ./ src/main/java/org/apache/tapestry/ src/main/java/org/apache/tapestry/corelib/components/ src/main/java/org/apache/tapestry/internal/ src/main/java/org/apache/tapestry/internal/b...

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ClassFabImplTest.java Mon Nov 20 16:05:16 2006
@@ -12,458 +12,457 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-package org.apache.tapestry.internal.ioc.services;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.DataFormatException;
-
-import javassist.CtClass;
-
-import org.apache.commons.logging.LogFactory;
-import org.apache.tapestry.BaseLocatable;
-import org.apache.tapestry.internal.ioc.services.LoggingDecoratorImplTest.ToStringService;
-import org.apache.tapestry.ioc.services.ClassFab;
-import org.apache.tapestry.ioc.services.MethodSignature;
-import org.apache.tapestry.ioc.services.PropertyAccess;
-import org.apache.tapestry.test.BaseTestCase;
-import org.testng.annotations.Test;
-
-/**
- * 
- */
-public class ClassFabImplTest extends BaseTestCase
-{
-    private final CtClassSource _source;
-
-    private final PropertyAccess _access = new PropertyAccessImpl();
-
-    public interface SampleService
-    {
-        int primitiveMethod(int primitiveValue);
-
-        void voidMethod(String input);
-
-        String objectMethod(String input);
-    }
-
-    public interface SampleToStringService
-    {
-        String toString();
-    }
-
-    public ClassFabImplTest()
-    {
-        ClassLoader threadLoader = Thread.currentThread().getContextClassLoader();
-
-        ClassFactoryClassPool pool = new ClassFactoryClassPool(threadLoader);
-
-        pool.addClassLoaderIfNeeded(threadLoader);
-
-        _source = new CtClassSource(pool);
-    }
-
-    private ClassFab newClassFab(String className, Class superClass)
-    {
-        CtClass ctClass = _source.newClass(className, superClass);
-
-        return new ClassFabImpl(_source, ctClass, LogFactory.getLog("ClassFab"));
-    }
-
-    @Test
-    public void create_simple_bean() throws Exception
-    {
-        ClassFab cf = newClassFab("TargetBean", Object.class);
-
-        cf.addField("_stringValue", String.class);
-
-        MethodSignature setStringValue = new MethodSignature(void.class, "setStringValue",
-                new Class[]
-                { String.class }, null);
-
-        cf.addMethod(Modifier.PUBLIC, setStringValue, "_stringValue = $1;");
-
-        MethodSignature getStringValue = new MethodSignature(String.class, "getStringValue", null,
-                null);
-
-        cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
-
-        Class targetClass = cf.createClass();
-
-        Object targetBean = targetClass.newInstance();
-
-        _access.set(targetBean, "stringValue", "Fred");
-
-        // May keep a test-time dependency on HiveMind, just for PropertyUtils.
-
-        String actual = (String) _access.get(targetBean, "stringValue");
-
-        assertEquals(actual, "Fred");
-    }
-
-    @Test
-    public void add_to_string() throws Exception
-    {
-        ClassFab cf = newClassFab("ToString", Object.class);
-
-        cf.addToString("ToString Description");
-
-        Class clazz = cf.createClass();
-
-        Object instance = clazz.newInstance();
-
-        assertEquals(instance.toString(), "ToString Description");
-    }
-
-    @Test
-    public void proxy_methods_to_delegate() throws Exception
-    {
-        ClassFab cf = newClassFab("Delegator", Object.class);
-
-        cf.addField("_delegate", SampleService.class);
-        cf.addConstructor(new Class[]
-        { SampleService.class }, null, "_delegate = $1;");
-
-        cf.proxyMethodsToDelegate(SampleService.class, "_delegate", "<Delegator>");
-
-        SampleService delegate = newMock(SampleService.class);
-
-        Class clazz = cf.createClass();
-
-        SampleService proxy = (SampleService) clazz.getConstructors()[0].newInstance(delegate);
-
-        delegate.primitiveMethod(5);
-        setReturnValue(10);
-
-        delegate.voidMethod("fred");
-
-        delegate.objectMethod("barney");
-        setReturnValue("rubble");
-
-        replay();
-
-        assertEquals(proxy.primitiveMethod(5), 10);
-
-        proxy.voidMethod("fred");
-
-        assertEquals(proxy.objectMethod("barney"), "rubble");
-        assertEquals(proxy.toString(), "<Delegator>");
-
-        verify();
-    }
-
-    @Test
-    public void proxy_methods_to_delegate_with_to_string() throws Exception
-    {
-        ClassFab cf = newClassFab("ToStringDelegator", Object.class);
-
-        cf.addField("_delegate", ToStringService.class);
-        cf.addConstructor(new Class[]
-        { ToStringService.class }, null, "_delegate = $1;");
-
-        cf.proxyMethodsToDelegate(ToStringService.class, "_delegate", "<ToStringDelegator>");
-
-        ToStringService delegate = new ToStringService()
-        {
-            @Override
-            public String toString()
-            {
-                return "ACTUAL TO-STRING";
-            }
-        };
-
-        Class clazz = cf.createClass();
-
-        ToStringService proxy = (ToStringService) clazz.getConstructors()[0].newInstance(delegate);
-
-        assertEquals(proxy.toString(), "ACTUAL TO-STRING");
-    }
-
-    @Test
-    public void add_constructor() throws Exception
-    {
-        ClassFab cf = newClassFab("ConstructableBean", Object.class);
-
-        cf.addField("_stringValue", String.class);
-        cf.addConstructor(new Class[]
-        { String.class }, null, "{ _stringValue = $1; }");
-
-        MethodSignature getStringValue = new MethodSignature(String.class, "getStringValue", null,
-                null);
-
-        cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
-
-        Class targetClass = cf.createClass();
-
-        try
-        {
-            targetClass.newInstance();
-            unreachable();
-        }
-        catch (InstantiationException ex)
-        {
-        }
-
-        Constructor c = targetClass.getConstructors()[0];
-
-        Object targetBean = c.newInstance(new Object[]
-        { "Buffy" });
-
-        String actual = (String) _access.get(targetBean, "stringValue");
-
-        assertEquals("Buffy", actual);
-    }
-
-    @Test
-    public void add_constructor_from_base_class() throws Exception
-    {
-        ClassFab cf = newClassFab("MyIntHolder", AbstractIntWrapper.class);
-
-        cf.addField("_intValue", int.class);
-        cf.addConstructor(new Class[]
-        { int.class }, null, "{ _intValue = $1; }");
-
-        cf.addMethod(
-                Modifier.PUBLIC,
-                new MethodSignature(int.class, "getIntValue", null, null),
-                "return _intValue;");
-
-        Class targetClass = cf.createClass();
-        Constructor c = targetClass.getConstructors()[0];
-
-        AbstractIntWrapper targetBean = (AbstractIntWrapper) c.newInstance(new Object[]
-        { new Integer(137) });
-
-        assertEquals(targetBean.getIntValue(), 137);
-    }
-
-    @Test
-    public void invalid_super_class() throws Exception
-    {
-        ClassFab cf = newClassFab("InvalidSuperClass", List.class);
-
-        try
-        {
-            cf.createClass();
-            unreachable();
-        }
-        catch (RuntimeException ex)
-        {
-            assertExceptionSubstring(ex, "Unable to create class InvalidSuperClass");
-        }
-    }
-
-    private void assertExceptionSubstring(Throwable t, String partialMessage)
-    {
-        assertTrue(t.getMessage().contains(partialMessage));
-    }
-
-    @Test
-    public void add_interface() throws Exception
-    {
-        ClassFab cf = newClassFab("SimpleService", Object.class);
-
-        cf.addInterface(SimpleService.class);
-
-        cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "add", new Class[]
-        { int.class, int.class }, null), "return $1 + $2;");
-
-        Class targetClass = cf.createClass();
-
-        SimpleService s = (SimpleService) targetClass.newInstance();
-
-        assertEquals(207, s.add(99, 108));
-    }
-
-    @Test
-    public void attempt_to_subclass_from_final_class() throws Exception
-    {
-        ClassFab cf = newClassFab("StringSubclass", String.class);
-
-        try
-        {
-            cf.createClass();
-        }
-        catch (RuntimeException ex)
-        {
-            assertExceptionRegexp(
-                    ex,
-                    "Unable to create class StringSubclass\\:.*Cannot inherit from final class");
-        }
-    }
-
-    private void assertExceptionRegexp(Throwable ex, String pattern)
-    {
-        assertTrue(ex.getMessage().matches(pattern));
-    }
-
-    @Test
-    public void create_class_within_non_default_package() throws Exception
-    {
-        ClassFab cf = newClassFab("org.apache.hivemind.InPackage", Object.class);
-
-        Class c = cf.createClass();
-
-        Object o = c.newInstance();
-
-        assertEquals("org.apache.hivemind.InPackage", o.getClass().getName());
-    }
-
-    @Test
-    public void invalid_method_body() throws Exception
-    {
-        ClassFab cf = newClassFab("BadMethodBody", Object.class);
-
-        cf.addInterface(Runnable.class);
-
-        try
-        {
-            cf.addMethod(
-                    Modifier.PUBLIC,
-                    new MethodSignature(void.class, "run", null, null),
-                    "fail;");
-        }
-        catch (RuntimeException ex)
-        {
-            assertExceptionSubstring(ex, "Unable to add method void run() to class BadMethodBody:");
-        }
-    }
-
-    @Test
-    public void add_duplicate_method_signature() throws Exception
-    {
-        ClassFab cf = newClassFab("DupeMethodAdd", Object.class);
-
-        cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
-
-        try
-        {
-            cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
-            unreachable();
-        }
-        catch (RuntimeException ex)
-        {
-            assertEquals("Attempt to redefine method void foo() of class DupeMethodAdd.", ex
-                    .getMessage());
-        }
-    }
-
-    @Test
-    public void invalid_constructor_body() throws Exception
-    {
-        ClassFab cf = newClassFab("BadConstructor", Object.class);
-
-        try
-        {
-            cf.addConstructor(null, null, " woops!");
-        }
-        catch (RuntimeException ex)
-        {
-            assertExceptionSubstring(ex, "Unable to add constructor to class BadConstructor");
-        }
-
-    }
-
-    @Test
-    public void invalid_field() throws Exception
-    {
-        ClassFab cf = newClassFab("InvalidField", Object.class);
-
-        // You'd think some of these would fail, but the ultimate failure
-        // occurs when we create the class.
-
-        cf.addField("a%b", String.class);
-        cf.addField("", int.class);
-
-        // Aha! Adding a duplicate fails!
-
-        cf.addField("buffy", int.class);
-
-        try
-        {
-            cf.addField("buffy", String.class);
-            unreachable();
-        }
-        catch (RuntimeException ex)
-        {
-            assertEquals(
-                    ex.getMessage(),
-                    "Unable to add field buffy to class InvalidField: duplicate field: buffy");
-        }
-
-    }
-
-    @Test
-    public void to_string() throws Exception
-    {
-        ClassFab cf = newClassFab("FredRunnable", BaseLocatable.class);
-
-        cf.addInterface(Runnable.class);
-        cf.addInterface(Serializable.class);
-
-        cf.addField("_map", Map.class);
-
-        cf.addConstructor(new Class[]
-        { Map.class, Runnable.class }, new Class[]
-        { IllegalArgumentException.class, DataFormatException.class }, "{ _map = $1; }");
-
-        MethodSignature sig = new MethodSignature(Map.class, "doTheNasty", new Class[]
-        { int.class, String.class }, new Class[]
-        { InstantiationException.class, IllegalAccessException.class });
-
-        cf.addMethod(
-                Modifier.PUBLIC + Modifier.FINAL + Modifier.SYNCHRONIZED,
-                sig,
-                "{ return _map; }");
-
-        String toString = cf.toString();
-
-        assertContains(
-                toString,
-                "public class FredRunnable extends org.apache.tapestry.BaseLocatable\n"
-                        + "  implements java.lang.Runnable, java.io.Serializable");
-
-        assertContains(toString, "private java.util.Map _map;");
-
-        assertContains(
-                toString,
-                "public FredRunnable(java.util.Map $1, java.lang.Runnable $2)\n"
-                        + "  throws java.lang.IllegalArgumentException, java.util.zip.DataFormatException\n"
-                        + "{ _map = $1; }");
-
-        assertContains(
-                toString,
-                "public final synchronized java.util.Map doTheNasty(int $1, java.lang.String $2)\n"
-                        + "  throws java.lang.InstantiationException, java.lang.IllegalAccessException\n"
-                        + "{ return _map; }");
-
-    }
-
-    @Test
-    public void add_noop_method() throws Exception
-    {
-        ClassFab cf = newClassFab("NoOp", Object.class);
-        cf.addInterface(Runnable.class);
-
-        cf.addNoOpMethod(new MethodSignature(void.class, "run", null, null));
-        cf.addNoOpMethod(new MethodSignature(int.class, "getInt", null, null));
-        cf.addNoOpMethod(new MethodSignature(double.class, "getDouble", null, null));
-
-        Class clazz = cf.createClass();
-
-        Runnable instance = (Runnable) clazz.newInstance();
-
-        instance.run();
-
-        assertEquals(_access.get(instance, "int"), 0);
-        assertEquals(_access.get(instance, "double"), 0.0d);
-    }
-
-    private void assertContains(String actual, String expectedSubstring)
-    {
-        assertTrue(actual.contains(expectedSubstring), "Missing substring: " + expectedSubstring);
-    }
-}
+package org.apache.tapestry.internal.ioc.services;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.DataFormatException;
+
+import javassist.CtClass;
+
+import org.apache.commons.logging.LogFactory;
+import org.apache.tapestry.internal.ioc.services.LoggingDecoratorImplTest.ToStringService;
+import org.apache.tapestry.ioc.BaseLocatable;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.MethodSignature;
+import org.apache.tapestry.ioc.services.PropertyAccess;
+import org.apache.tapestry.test.BaseTestCase;
+import org.testng.annotations.Test;
+
+/**
+ * 
+ */
+public class ClassFabImplTest extends BaseTestCase
+{
+    private final CtClassSource _source;
+
+    private final PropertyAccess _access = new PropertyAccessImpl();
+
+    public interface SampleService
+    {
+        int primitiveMethod(int primitiveValue);
+
+        void voidMethod(String input);
+
+        String objectMethod(String input);
+    }
+
+    public interface SampleToStringService
+    {
+        String toString();
+    }
+
+    public ClassFabImplTest()
+    {
+        ClassLoader threadLoader = Thread.currentThread().getContextClassLoader();
+
+        ClassFactoryClassPool pool = new ClassFactoryClassPool(threadLoader);
+
+        pool.addClassLoaderIfNeeded(threadLoader);
+
+        _source = new CtClassSource(pool);
+    }
+
+    private ClassFab newClassFab(String className, Class superClass)
+    {
+        CtClass ctClass = _source.newClass(className, superClass);
+
+        return new ClassFabImpl(_source, ctClass, LogFactory.getLog("ClassFab"));
+    }
+
+    @Test
+    public void create_simple_bean() throws Exception
+    {
+        ClassFab cf = newClassFab("TargetBean", Object.class);
+
+        cf.addField("_stringValue", String.class);
+
+        MethodSignature setStringValue = new MethodSignature(void.class, "setStringValue",
+                new Class[]
+                { String.class }, null);
+
+        cf.addMethod(Modifier.PUBLIC, setStringValue, "_stringValue = $1;");
+
+        MethodSignature getStringValue = new MethodSignature(String.class, "getStringValue", null,
+                null);
+
+        cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
+
+        Class targetClass = cf.createClass();
+
+        Object targetBean = targetClass.newInstance();
+
+        _access.set(targetBean, "stringValue", "Fred");
+
+        // May keep a test-time dependency on HiveMind, just for PropertyUtils.
+
+        String actual = (String) _access.get(targetBean, "stringValue");
+
+        assertEquals(actual, "Fred");
+    }
+
+    @Test
+    public void add_to_string() throws Exception
+    {
+        ClassFab cf = newClassFab("ToString", Object.class);
+
+        cf.addToString("ToString Description");
+
+        Class clazz = cf.createClass();
+
+        Object instance = clazz.newInstance();
+
+        assertEquals(instance.toString(), "ToString Description");
+    }
+
+    @Test
+    public void proxy_methods_to_delegate() throws Exception
+    {
+        ClassFab cf = newClassFab("Delegator", Object.class);
+
+        cf.addField("_delegate", SampleService.class);
+        cf.addConstructor(new Class[]
+        { SampleService.class }, null, "_delegate = $1;");
+
+        cf.proxyMethodsToDelegate(SampleService.class, "_delegate", "<Delegator>");
+
+        SampleService delegate = newMock(SampleService.class);
+
+        Class clazz = cf.createClass();
+
+        SampleService proxy = (SampleService) clazz.getConstructors()[0].newInstance(delegate);
+
+        delegate.primitiveMethod(5);
+        setReturnValue(10);
+
+        delegate.voidMethod("fred");
+
+        delegate.objectMethod("barney");
+        setReturnValue("rubble");
+
+        replay();
+
+        assertEquals(proxy.primitiveMethod(5), 10);
+
+        proxy.voidMethod("fred");
+
+        assertEquals(proxy.objectMethod("barney"), "rubble");
+        assertEquals(proxy.toString(), "<Delegator>");
+
+        verify();
+    }
+
+    @Test
+    public void proxy_methods_to_delegate_with_to_string() throws Exception
+    {
+        ClassFab cf = newClassFab("ToStringDelegator", Object.class);
+
+        cf.addField("_delegate", ToStringService.class);
+        cf.addConstructor(new Class[]
+        { ToStringService.class }, null, "_delegate = $1;");
+
+        cf.proxyMethodsToDelegate(ToStringService.class, "_delegate", "<ToStringDelegator>");
+
+        ToStringService delegate = new ToStringService()
+        {
+            @Override
+            public String toString()
+            {
+                return "ACTUAL TO-STRING";
+            }
+        };
+
+        Class clazz = cf.createClass();
+
+        ToStringService proxy = (ToStringService) clazz.getConstructors()[0].newInstance(delegate);
+
+        assertEquals(proxy.toString(), "ACTUAL TO-STRING");
+    }
+
+    @Test
+    public void add_constructor() throws Exception
+    {
+        ClassFab cf = newClassFab("ConstructableBean", Object.class);
+
+        cf.addField("_stringValue", String.class);
+        cf.addConstructor(new Class[]
+        { String.class }, null, "{ _stringValue = $1; }");
+
+        MethodSignature getStringValue = new MethodSignature(String.class, "getStringValue", null,
+                null);
+
+        cf.addMethod(Modifier.PUBLIC, getStringValue, "return _stringValue;");
+
+        Class targetClass = cf.createClass();
+
+        try
+        {
+            targetClass.newInstance();
+            unreachable();
+        }
+        catch (InstantiationException ex)
+        {
+        }
+
+        Constructor c = targetClass.getConstructors()[0];
+
+        Object targetBean = c.newInstance(new Object[]
+        { "Buffy" });
+
+        String actual = (String) _access.get(targetBean, "stringValue");
+
+        assertEquals("Buffy", actual);
+    }
+
+    @Test
+    public void add_constructor_from_base_class() throws Exception
+    {
+        ClassFab cf = newClassFab("MyIntHolder", AbstractIntWrapper.class);
+
+        cf.addField("_intValue", int.class);
+        cf.addConstructor(new Class[]
+        { int.class }, null, "{ _intValue = $1; }");
+
+        cf.addMethod(
+                Modifier.PUBLIC,
+                new MethodSignature(int.class, "getIntValue", null, null),
+                "return _intValue;");
+
+        Class targetClass = cf.createClass();
+        Constructor c = targetClass.getConstructors()[0];
+
+        AbstractIntWrapper targetBean = (AbstractIntWrapper) c.newInstance(new Object[]
+        { new Integer(137) });
+
+        assertEquals(targetBean.getIntValue(), 137);
+    }
+
+    @Test
+    public void invalid_super_class() throws Exception
+    {
+        ClassFab cf = newClassFab("InvalidSuperClass", List.class);
+
+        try
+        {
+            cf.createClass();
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionSubstring(ex, "Unable to create class InvalidSuperClass");
+        }
+    }
+
+    private void assertExceptionSubstring(Throwable t, String partialMessage)
+    {
+        assertTrue(t.getMessage().contains(partialMessage));
+    }
+
+    @Test
+    public void add_interface() throws Exception
+    {
+        ClassFab cf = newClassFab("SimpleService", Object.class);
+
+        cf.addInterface(SimpleService.class);
+
+        cf.addMethod(Modifier.PUBLIC, new MethodSignature(int.class, "add", new Class[]
+        { int.class, int.class }, null), "return $1 + $2;");
+
+        Class targetClass = cf.createClass();
+
+        SimpleService s = (SimpleService) targetClass.newInstance();
+
+        assertEquals(207, s.add(99, 108));
+    }
+
+    @Test
+    public void attempt_to_subclass_from_final_class() throws Exception
+    {
+        ClassFab cf = newClassFab("StringSubclass", String.class);
+
+        try
+        {
+            cf.createClass();
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionRegexp(
+                    ex,
+                    "Unable to create class StringSubclass\\:.*Cannot inherit from final class");
+        }
+    }
+
+    private void assertExceptionRegexp(Throwable ex, String pattern)
+    {
+        assertTrue(ex.getMessage().matches(pattern));
+    }
+
+    @Test
+    public void create_class_within_non_default_package() throws Exception
+    {
+        ClassFab cf = newClassFab("org.apache.hivemind.InPackage", Object.class);
+
+        Class c = cf.createClass();
+
+        Object o = c.newInstance();
+
+        assertEquals("org.apache.hivemind.InPackage", o.getClass().getName());
+    }
+
+    @Test
+    public void invalid_method_body() throws Exception
+    {
+        ClassFab cf = newClassFab("BadMethodBody", Object.class);
+
+        cf.addInterface(Runnable.class);
+
+        try
+        {
+            cf.addMethod(
+                    Modifier.PUBLIC,
+                    new MethodSignature(void.class, "run", null, null),
+                    "fail;");
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionSubstring(ex, "Unable to add method void run() to class BadMethodBody:");
+        }
+    }
+
+    @Test
+    public void add_duplicate_method_signature() throws Exception
+    {
+        ClassFab cf = newClassFab("DupeMethodAdd", Object.class);
+
+        cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
+
+        try
+        {
+            cf.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "foo", null, null), "{}");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals("Attempt to redefine method void foo() of class DupeMethodAdd.", ex
+                    .getMessage());
+        }
+    }
+
+    @Test
+    public void invalid_constructor_body() throws Exception
+    {
+        ClassFab cf = newClassFab("BadConstructor", Object.class);
+
+        try
+        {
+            cf.addConstructor(null, null, " woops!");
+        }
+        catch (RuntimeException ex)
+        {
+            assertExceptionSubstring(ex, "Unable to add constructor to class BadConstructor");
+        }
+
+    }
+
+    @Test
+    public void invalid_field() throws Exception
+    {
+        ClassFab cf = newClassFab("InvalidField", Object.class);
+
+        // You'd think some of these would fail, but the ultimate failure
+        // occurs when we create the class.
+
+        cf.addField("a%b", String.class);
+        cf.addField("", int.class);
+
+        // Aha! Adding a duplicate fails!
+
+        cf.addField("buffy", int.class);
+
+        try
+        {
+            cf.addField("buffy", String.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertEquals(
+                    ex.getMessage(),
+                    "Unable to add field buffy to class InvalidField: duplicate field: buffy");
+        }
+
+    }
+
+    @Test
+    public void to_string() throws Exception
+    {
+        ClassFab cf = newClassFab("FredRunnable", BaseLocatable.class);
+
+        cf.addInterface(Runnable.class);
+        cf.addInterface(Serializable.class);
+
+        cf.addField("_map", Map.class);
+
+        cf.addConstructor(new Class[]
+        { Map.class, Runnable.class }, new Class[]
+        { IllegalArgumentException.class, DataFormatException.class }, "{ _map = $1; }");
+
+        MethodSignature sig = new MethodSignature(Map.class, "doTheNasty", new Class[]
+        { int.class, String.class }, new Class[]
+        { InstantiationException.class, IllegalAccessException.class });
+
+        cf.addMethod(
+                Modifier.PUBLIC + Modifier.FINAL + Modifier.SYNCHRONIZED,
+                sig,
+                "{ return _map; }");
+
+        String toString = cf.toString();
+
+        assertContains(toString, "public class FredRunnable extends "
+                + BaseLocatable.class.getName() + "\n"
+                + "  implements java.lang.Runnable, java.io.Serializable");
+
+        assertContains(toString, "private java.util.Map _map;");
+
+        assertContains(
+                toString,
+                "public FredRunnable(java.util.Map $1, java.lang.Runnable $2)\n"
+                        + "  throws java.lang.IllegalArgumentException, java.util.zip.DataFormatException\n"
+                        + "{ _map = $1; }");
+
+        assertContains(
+                toString,
+                "public final synchronized java.util.Map doTheNasty(int $1, java.lang.String $2)\n"
+                        + "  throws java.lang.InstantiationException, java.lang.IllegalAccessException\n"
+                        + "{ return _map; }");
+
+    }
+
+    @Test
+    public void add_noop_method() throws Exception
+    {
+        ClassFab cf = newClassFab("NoOp", Object.class);
+        cf.addInterface(Runnable.class);
+
+        cf.addNoOpMethod(new MethodSignature(void.class, "run", null, null));
+        cf.addNoOpMethod(new MethodSignature(int.class, "getInt", null, null));
+        cf.addNoOpMethod(new MethodSignature(double.class, "getDouble", null, null));
+
+        Class clazz = cf.createClass();
+
+        Runnable instance = (Runnable) clazz.newInstance();
+
+        instance.run();
+
+        assertEquals(_access.get(instance, "int"), 0);
+        assertEquals(_access.get(instance, "double"), 0.0d);
+    }
+
+    private void assertContains(String actual, String expectedSubstring)
+    {
+        assertTrue(actual.contains(expectedSubstring), "Missing substring: " + expectedSubstring);
+    }
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ExceptionAnalyzerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ExceptionAnalyzerImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ExceptionAnalyzerImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/ExceptionAnalyzerImplTest.java Mon Nov 20 16:05:16 2006
@@ -16,9 +16,9 @@
 
 import java.util.Arrays;
 
-import org.apache.tapestry.Location;
 import org.apache.tapestry.internal.TapestryException;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.ioc.services.ExceptionAnalysis;
 import org.apache.tapestry.ioc.services.ExceptionAnalyzer;
 import org.apache.tapestry.ioc.services.ExceptionInfo;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/model/MutableComponentModelImplTest.java Mon Nov 20 16:05:16 2006
@@ -17,8 +17,8 @@
 import java.util.Arrays;
 
 import org.apache.commons.logging.Log;
-import org.apache.tapestry.Resource;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.model.MutableComponentModel;
 import org.apache.tapestry.model.MutableEmbeddedComponentModel;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/BindingSourceImplTest.java Mon Nov 20 16:05:16 2006
@@ -20,9 +20,9 @@
 
 import org.apache.tapestry.Binding;
 import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.Location;
 import org.apache.tapestry.internal.TapestryException;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.services.BindingFactory;
 import org.apache.tapestry.services.BindingSource;
 import org.testng.annotations.Test;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/ComponentTemplateSourceImplTest.java Mon Nov 20 16:05:16 2006
@@ -19,11 +19,11 @@
 import java.net.URLClassLoader;
 import java.util.Locale;
 
-import org.apache.tapestry.Resource;
 import org.apache.tapestry.events.InvalidationListener;
 import org.apache.tapestry.internal.ClasspathResource;
 import org.apache.tapestry.internal.parser.ComponentTemplate;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Resource;
 import org.testng.annotations.Test;
 
 /**

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageElementFactoryImplTest.java Mon Nov 20 16:05:16 2006
@@ -14,7 +14,6 @@
 
 package org.apache.tapestry.internal.services;
 
-import org.apache.tapestry.Location;
 import org.apache.tapestry.MarkupWriter;
 import org.apache.tapestry.dom.MarkupModel;
 import org.apache.tapestry.dom.XMLMarkupModel;
@@ -24,6 +23,7 @@
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.internal.structure.PageElement;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.runtime.RenderQueue;
 import org.apache.tapestry.services.ComponentClassResolver;
 import org.testng.annotations.Test;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/PageLoaderImplTest.java Mon Nov 20 16:05:16 2006
@@ -18,7 +18,6 @@
 import java.util.Locale;
 
 import org.apache.commons.logging.Log;
-import org.apache.tapestry.Location;
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.parser.ComponentTemplate;
 import org.apache.tapestry.internal.parser.EndElementToken;
@@ -26,6 +25,7 @@
 import org.apache.tapestry.internal.structure.ComponentPageElement;
 import org.apache.tapestry.internal.structure.PageElement;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.model.EmbeddedComponentModel;
 import org.apache.tapestry.services.BindingSource;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/services/TemplateParserImplTest.java Mon Nov 20 16:05:16 2006
@@ -22,9 +22,6 @@
 import java.util.Set;
 
 import org.apache.commons.logging.Log;
-import org.apache.tapestry.Locatable;
-import org.apache.tapestry.Location;
-import org.apache.tapestry.Resource;
 import org.apache.tapestry.internal.ClasspathResource;
 import org.apache.tapestry.internal.TapestryException;
 import org.apache.tapestry.internal.parser.AttributeToken;
@@ -38,6 +35,9 @@
 import org.apache.tapestry.internal.parser.StartElementToken;
 import org.apache.tapestry.internal.parser.TemplateToken;
 import org.apache.tapestry.internal.parser.TextToken;
+import org.apache.tapestry.ioc.Locatable;
+import org.apache.tapestry.ioc.Location;
+import org.apache.tapestry.ioc.Resource;
 import org.apache.tapestry.test.BaseTestCase;
 import org.testng.annotations.Test;
 

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/structure/ComponentPageElementImplTest.java Mon Nov 20 16:05:16 2006
@@ -17,11 +17,11 @@
 import org.apache.commons.logging.Log;
 import org.apache.tapestry.Binding;
 import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.Location;
 import org.apache.tapestry.internal.InternalComponentResources;
 import org.apache.tapestry.internal.TapestryException;
 import org.apache.tapestry.internal.services.Instantiator;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.ioc.services.TypeCoercer;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.model.ParameterModel;

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/InternalUtilsTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/InternalUtilsTest.java?view=diff&rev=477421&r1=477420&r2=477421
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/InternalUtilsTest.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/util/InternalUtilsTest.java Mon Nov 20 16:05:16 2006
@@ -26,9 +26,9 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.tapestry.Locatable;
-import org.apache.tapestry.Location;
 import org.apache.tapestry.internal.test.InternalBaseTestCase;
+import org.apache.tapestry.ioc.Locatable;
+import org.apache.tapestry.ioc.Location;
 import org.apache.tapestry.util.CollectionFactory;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;