Author: hlship
Date: Mon Oct 13 11:01:03 2008
New Revision: 704190

URL: http://svn.apache.org/viewvc?rev=704190&view=rev
Log:
TAP5-275: Add set() method to TestBase to allow private fields of objects to be 
set via reflection

Added:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/Bean.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java
    
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java
Modified:
    
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/test/TestBase.java
    tapestry/tapestry5/trunk/tapestry-ioc/src/test/conf/testng.xml
    tapestry/tapestry5/trunk/tapestry-tutorial1/tutorial1.iml

Modified: 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/test/TestBase.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/test/TestBase.java?rev=704190&r1=704189&r2=704190&view=diff
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/test/TestBase.java
 (original)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/test/TestBase.java
 Mon Oct 13 11:01:03 2008
@@ -14,10 +14,13 @@
 
 package org.apache.tapestry5.ioc.test;
 
+import org.apache.tapestry5.ioc.internal.util.Defense;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
 import org.easymock.*;
 import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
 
+import java.lang.reflect.Field;
 import java.util.Arrays;
 import java.util.List;
 
@@ -35,12 +38,10 @@
  * functionality using [EMAIL PROTECTED] MockTester}.
  * <p/>
  * This class is thread safe (it uses a thread local to store the mock 
control). In theory, this should allow TestNG to
- * execute tests in parallel. Unfortunately, as of this writing (TestNG 5.1 
and maven-surefire 2.8-SNAPSHOT) parallel
- * execution does not always work fully and consistently, some tests are 
dropped, and so Tapestry does not make use of
- * TestNG parallel execution.
+ * execute tests in parallel.
  *
- * @see EasyMock#createControl()
- * @see MockTester
+ * @see org.easymock.EasyMock#createControl()
+ * @see org.apache.tapestry5.ioc.test.MockTester
  */
 public class TestBase extends Assert
 {
@@ -108,7 +109,7 @@
      *
      * @param throwable the exception to be thrown by the most recent method 
call on any mock
      */
-    protected static final void setThrowable(Throwable throwable)
+    protected static void setThrowable(Throwable throwable)
     {
         EasyMock.expectLastCall().andThrow(throwable);
     }
@@ -118,7 +119,7 @@
      *
      * @param answer callback for the most recent method invocation
      */
-    protected static final void setAnswer(IAnswer answer)
+    protected static void setAnswer(IAnswer answer)
     {
         EasyMock.expectLastCall().andAnswer(answer);
     }
@@ -128,7 +129,7 @@
      * method that is expected to throw an exception.
      */
 
-    protected static final void unreachable()
+    protected static void unreachable()
     {
         fail("This code should not be reachable.");
     }
@@ -141,7 +142,7 @@
      * @return expectation setter, for setting return value, etc.
      */
     @SuppressWarnings("unchecked")
-    protected static final <T> IExpectationSetters<T> expect(T value)
+    protected static <T> IExpectationSetters<T> expect(T value)
     {
         return EasyMock.expect(value);
     }
@@ -152,7 +153,7 @@
      * @param t          throwable to check
      * @param substrings some number of expected substrings
      */
-    protected static final void assertMessageContains(Throwable t, String... 
substrings)
+    protected static void assertMessageContains(Throwable t, String... 
substrings)
     {
         String message = t.getMessage();
 
@@ -170,7 +171,7 @@
      * @param actual   actual values to check
      * @param expected expected values
      */
-    protected static final <T> void assertListsEquals(List<T> actual, List<T> 
expected)
+    protected static <T> void assertListsEquals(List<T> actual, List<T> 
expected)
     {
         int count = Math.min(actual.size(), expected.size());
 
@@ -189,7 +190,7 @@
      * @param actual   actual values to check
      * @param expected expected values
      */
-    protected static final <T> void assertListsEquals(List<T> actual, T... 
expected)
+    protected static <T> void assertListsEquals(List<T> actual, T... expected)
     {
         assertListsEquals(actual, Arrays.asList(expected));
     }
@@ -201,7 +202,7 @@
      * @param actual   actual values to check
      * @param expected expected values
      */
-    protected static final <T> void assertArraysEqual(T[] actual, T... 
expected)
+    protected static <T> void assertArraysEqual(T[] actual, T... expected)
     {
         assertListsEquals(Arrays.asList(actual), expected);
     }
@@ -209,8 +210,93 @@
     /**
      * A factory method to create EasyMock Capture objects.
      */
-    protected static final <T> Capture<T> newCapture()
+    protected static <T> Capture<T> newCapture()
     {
         return new Capture<T>();
     }
+
+    /**
+     * Creates a new instance of the object using its default constructor, and 
initializes it (via [EMAIL PROTECTED] #set(Object,
+     * Object[])}).
+     *
+     * @param objectType  typeof object to instantiate
+     * @param fieldValues string field names and corresponding field values
+     * @return the initialized instance
+     */
+    protected static <T> T create(Class<T> objectType, Object... fieldValues)
+    {
+        T result = null;
+
+        try
+        {
+            result = objectType.newInstance();
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException(String.format("Unable to instantiate 
instance of %s: %s",
+                                                     objectType.getName(), 
InternalUtils.toMessage(ex)), ex);
+        }
+
+        return set(result, fieldValues);
+    }
+
+    /**
+     * Initializes private fields (via reflection).
+     *
+     * @param object      object to be updated
+     * @param fieldValues string field names and corresponding field values
+     * @return the object
+     */
+    protected static <T> T set(T object, Object... fieldValues)
+    {
+        Defense.notNull(object, "object");
+
+        Class objectClass = object.getClass();
+
+        for (int i = 0; i < fieldValues.length; i += 2)
+        {
+            String fieldName = (String) fieldValues[i];
+            Object fieldValue = fieldValues[i + 1];
+
+            try
+            {
+                Field field = findField(objectClass, fieldName);
+
+                field.setAccessible(true);
+
+                field.set(object, fieldValue);
+            }
+            catch (Exception ex)
+            {
+                throw new RuntimeException(String.format("Unable to set field 
'%s' of %s to %s: %s",
+                                                         fieldName, object, 
fieldValue,
+                                                         
InternalUtils.toMessage(ex)), ex);
+            }
+        }
+
+        return object;
+    }
+
+    private static Field findField(Class objectClass, String fieldName)
+    {
+
+        Class cursor = objectClass;
+
+        while (cursor != null)
+        {
+            try
+            {
+                return cursor.getDeclaredField(fieldName);
+            }
+            catch (NoSuchFieldException ex)
+            {
+                // Ignore.
+            }
+
+            cursor = cursor.getSuperclass();
+        }
+
+        throw new RuntimeException(
+                String.format("Class %s does not contain a field named '%s'.", 
objectClass.getName(), fieldName));
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/conf/testng.xml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/conf/testng.xml?rev=704190&r1=704189&r2=704190&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/conf/testng.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/conf/testng.xml Mon Oct 13 
11:01:03 2008
@@ -20,6 +20,7 @@
         <packages>
             <package name="org.apache.tapestry5.ioc"/>
             <package name="org.apache.tapestry5.ioc.services"/>
+            <package name="org.apache.tapestry5.ioc.test"/>
             <package name="org.apache.tapestry5.ioc.util"/>
         </packages>
     </test>

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/Bean.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/Bean.java?rev=704190&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/Bean.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/Bean.java
 Mon Oct 13 11:01:03 2008
@@ -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.test;
+
+public class Bean
+{
+    private String value;
+
+    public String getValue()
+    {
+        return value;
+    }
+}

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java?rev=704190&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/BeanSubclass.java
 Mon Oct 13 11:01:03 2008
@@ -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.test;
+
+public class BeanSubclass extends Bean
+{
+    private boolean flag;
+
+    public boolean isFlag()
+    {
+        return flag;
+    }
+}

Added: 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java?rev=704190&view=auto
==============================================================================
--- 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java
 (added)
+++ 
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/test/TestBaseTest.java
 Mon Oct 13 11:01:03 2008
@@ -0,0 +1,80 @@
+//  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;
+
+import org.testng.annotations.Test;
+
+public class TestBaseTest extends TestBase
+{
+    @Test
+    public void create_instance()
+    {
+        Bean b = create(Bean.class, "value", "Magic");
+
+        assertEquals(b.getValue(), "Magic");
+    }
+
+    @Test
+    public void create_instance_failure()
+    {
+        try
+        {
+            create(Runnable.class);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Unable to instantiate instance of 
java.lang.Runnable");
+        }
+    }
+
+    @Test
+    public void create_instance_field_missing()
+    {
+        try
+        {
+            create(Bean.class, "unknownField", "doesn't matter");
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Unable to set field 'unknownField' of 
org.apache.tapestry5.ioc.test.Bean",
+                                  "Class org.apache.tapestry5.ioc.test.Bean 
does not contain a field named 'unknownField'.");
+        }
+    }
+
+    @Test
+    public void type_mismatch_when_setting_field_value()
+    {
+        try
+        {
+            create(Bean.class, "value", 99);
+            unreachable();
+        }
+        catch (RuntimeException ex)
+        {
+            assertMessageContains(ex, "Unable to set field 'value' of 
org.apache.tapestry5.ioc.test.Bean");
+        }
+    }
+
+    @Test
+    public void set_fields_from_base_class()
+    {
+        BeanSubclass b = create(BeanSubclass.class, "flag", true, "value", 
"magic");
+
+        assertEquals(b.isFlag(), true);
+        assertEquals(b.getValue(), "magic");
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-tutorial1/tutorial1.iml
URL: 
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-tutorial1/tutorial1.iml?rev=704190&r1=704189&r2=704190&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-tutorial1/tutorial1.iml (original)
+++ tapestry/tapestry5/trunk/tapestry-tutorial1/tutorial1.iml Mon Oct 13 
11:01:03 2008
@@ -23,19 +23,19 @@
         <packaging>
           <containerElement type="module" name="tapestry-hibernate">
             <attribute name="method" value="5" />
-            <attribute name="URI" 
value="/WEB-INF/lib/tapestry-hibernate-5.0.15.jar" />
+            <attribute name="URI" 
value="/WEB-INF/lib/tapestry-hibernate-5.0.16-SNAPSHOT.jar" />
           </containerElement>
           <containerElement type="module" name="tapestry-core">
             <attribute name="method" value="5" />
-            <attribute name="URI" 
value="/WEB-INF/lib/tapestry-core-5.0.15.jar" />
+            <attribute name="URI" 
value="/WEB-INF/lib/tapestry-core-5.0.16-SNAPSHOT.jar" />
           </containerElement>
           <containerElement type="module" name="tapestry-ioc">
             <attribute name="method" value="5" />
-            <attribute name="URI" value="/WEB-INF/lib/tapestry-ioc-5.0.15.jar" 
/>
+            <attribute name="URI" 
value="/WEB-INF/lib/tapestry-ioc-5.0.16-SNAPSHOT.jar" />
           </containerElement>
           <containerElement type="module" name="tapestry-annotations">
             <attribute name="method" value="5" />
-            <attribute name="URI" 
value="/WEB-INF/lib/tapestry5-annotations-5.0.15.jar" />
+            <attribute name="URI" 
value="/WEB-INF/lib/tapestry5-annotations-5.0.16-SNAPSHOT.jar" />
           </containerElement>
           <containerElement type="library" name="javassist:javassist:3.8.0.GA" 
level="module">
             <attribute name="method" value="1" />


Reply via email to