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 2005/03/30 19:43:33 UTC
cvs commit: jakarta-tapestry/framework/src/test/org/apache/tapestry/components BaseComponentTestCase.java
hlship 2005/03/30 09:43:33
Modified: framework/src/java/org/apache/tapestry/test Creator.java
framework/src/test/org/apache/tapestry/test TestCreator.java
framework/src/java/org/apache/tapestry TapestryMessages.java
BaseComponent.java AbstractComponent.java
TapestryStrings2.properties
framework/src/java/org/apache/tapestry/html BasePage.java
framework/src/test/org/apache/tapestry/components
BaseComponentTestCase.java
Added: framework/src/java/org/apache/tapestry/test
CreatePropertyWorker.java
framework/src/test/org/apache/tapestry
TestAbstractComponent.java
Log:
Convert the IComponent specification and messages properties back into concrete methods (that throw an exception).
Modify the Creator to ensure that these properties are read/write inside unit tests.
Revision Changes Path
1.8 +46 -14 jakarta-tapestry/framework/src/java/org/apache/tapestry/test/Creator.java
Index: Creator.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/test/Creator.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Creator.java 31 Jan 2005 05:36:22 -0000 1.7
+++ Creator.java 30 Mar 2005 17:43:33 -0000 1.8
@@ -14,8 +14,10 @@
package org.apache.tapestry.test;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
@@ -31,14 +33,23 @@
import org.apache.tapestry.Tapestry;
import org.apache.tapestry.enhance.AbstractPropertyWorker;
import org.apache.tapestry.enhance.EnhancementOperationImpl;
+import org.apache.tapestry.enhance.EnhancementWorker;
import org.apache.tapestry.services.ComponentConstructor;
import org.apache.tapestry.spec.ComponentSpecification;
/**
* A utility class that is used to instantiate abstract Tapestry pages and components. It creates,
- * at runtime, a subclass where all abstract properties are filled in (complete with instance
- * variable, accessor and mutator methods). This isn't the same as how the class is enhanced at
- * runtime, but is sufficient to unit test the class, especially listener methods.
+ * at runtime, a subclass where all abstract properties are filled in (each property complete with
+ * an instance variable, an accessor method and a mutator method). This isn't quite the same as how
+ * the class is enhanced at runtime (though it does use a subset of the same
+ * {@link org.apache.tapestry.enhance.EnhancementWorker code}), but is sufficient to unit test the
+ * class, especially listener methods.
+ * <p>
+ * One part of the enhancement is that the
+ * {@link org.apache.tapestry.IComponent#getSpecification() specification} and
+ * {@link org.apache.tapestry.IComponent#getMessages() messages} properties of the page or
+ * component class are converted into read/write properties that can be set via reflection
+ * (including {@link #newInstance(Class, Map)}.
*
* @author Howard Lewis Ship
* @since 3.1
@@ -56,19 +67,37 @@
private ClassResolver _classResolver = new DefaultClassResolver();
+ private List _workers = new ArrayList();
+
+ {
+ // Overrride AbstractComponent's implementations of
+ // these two properties (making them read/write).
+
+ _workers.add(new CreatePropertyWorker("messages"));
+ _workers.add(new CreatePropertyWorker("specification"));
+
+ // Implement any abstract properties.
+ // Note that we don't bother setting the errorLog property
+ // so failures may turn into NPEs.
+
+ _workers.add(new AbstractPropertyWorker());
+ }
+
private ComponentConstructor createComponentConstructor(Class inputClass)
{
if (inputClass.isInterface() || inputClass.isPrimitive() || inputClass.isArray())
throw new IllegalArgumentException(ScriptMessages.wrongTypeForEnhancement(inputClass));
- AbstractPropertyWorker w = new AbstractPropertyWorker();
-
- w.setErrorLog(new ErrorLogImpl(new DefaultErrorHandler(), LOG));
-
EnhancementOperationImpl op = new EnhancementOperationImpl(_classResolver,
new ComponentSpecification(), inputClass, _classFactory);
- w.performEnhancement(op, null);
+ Iterator i = _workers.iterator();
+ while (i.hasNext())
+ {
+ EnhancementWorker worker = (EnhancementWorker) i.next();
+
+ worker.performEnhancement(op, null);
+ }
return op.getConstructor();
}
@@ -115,15 +144,18 @@
{
Object result = newInstance(abstractClass);
- Iterator i = properties.entrySet().iterator();
-
- while (i.hasNext())
+ if (properties != null)
{
- Map.Entry e = (Map.Entry) i.next();
+ Iterator i = properties.entrySet().iterator();
+
+ while (i.hasNext())
+ {
+ Map.Entry e = (Map.Entry) i.next();
- String propertyName = (String) e.getKey();
+ String propertyName = (String) e.getKey();
- PropertyUtils.write(result, propertyName, e.getValue());
+ PropertyUtils.write(result, propertyName, e.getValue());
+ }
}
return result;
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/test/CreatePropertyWorker.java
Index: CreatePropertyWorker.java
===================================================================
// Copyright 2005 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.tapestry.test;
import org.apache.tapestry.enhance.EnhanceUtils;
import org.apache.tapestry.enhance.EnhancementOperation;
import org.apache.tapestry.enhance.EnhancementWorker;
import org.apache.tapestry.spec.IComponentSpecification;
/**
* Forces the creation of a property, overrriding an existing implementation. Allows test code to
* set the specification and messages properties of components.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class CreatePropertyWorker implements EnhancementWorker
{
private String _propertyName;
public CreatePropertyWorker(String propertyName)
{
_propertyName = propertyName;
}
public void performEnhancement(EnhancementOperation op, IComponentSpecification spec)
{
Class propertyType = EnhanceUtils.extractPropertyType(op, _propertyName, null);
op.claimProperty(_propertyName);
String field = "_$" + _propertyName;
op.addField(field, propertyType);
EnhanceUtils.createSimpleAccessor(op, field, _propertyName, propertyType);
EnhanceUtils.createSimpleMutator(op, field, _propertyName, propertyType);
}
}
1.5 +36 -0 jakarta-tapestry/framework/src/test/org/apache/tapestry/test/TestCreator.java
Index: TestCreator.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/test/TestCreator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TestCreator.java 6 Jan 2005 02:17:26 -0000 1.4
+++ TestCreator.java 30 Mar 2005 17:43:33 -0000 1.5
@@ -16,7 +16,11 @@
import java.util.List;
+import org.apache.hivemind.Messages;
import org.apache.hivemind.test.HiveMindTestCase;
+import org.apache.tapestry.AbstractComponent;
+import org.apache.tapestry.IComponent;
+import org.apache.tapestry.spec.IComponentSpecification;
/**
* Tests for {@link org.apache.tapestry.test.Creator}.
@@ -125,4 +129,36 @@
assertEquals("Hitchhiker's Guide", ss.getTitle());
}
+
+ public void testSpecificationProperty()
+ {
+ IComponentSpecification spec = (IComponentSpecification) newMock(IComponentSpecification.class);
+
+ replayControls();
+
+ Creator c = new Creator();
+
+ IComponent component = (IComponent) c.newInstance(AbstractComponent.class, new Object[]
+ { "specification", spec });
+
+ assertSame(spec, component.getSpecification());
+
+ verifyControls();
+ }
+
+ public void testMessagesProperty()
+ {
+ Messages messages = (Messages) newMock(Messages.class);
+
+ replayControls();
+
+ Creator c = new Creator();
+
+ IComponent component = (IComponent) c.newInstance(AbstractComponent.class, new Object[]
+ { "messages", messages });
+
+ assertSame(messages, component.getMessages());
+
+ verifyControls();
+ }
}
\ No newline at end of file
1.10 +6 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryMessages.java
Index: TapestryMessages.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryMessages.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- TapestryMessages.java 29 Mar 2005 13:35:42 -0000 1.9
+++ TapestryMessages.java 30 Mar 2005 17:43:33 -0000 1.10
@@ -46,8 +46,13 @@
return _formatter.format("non-unique-attribute", newInstance, key, existingInstance);
}
- public static String noPageRenderSupport()
+ static String noPageRenderSupport()
{
return _formatter.getMessage("no-page-render-support");
}
+
+ static String providedByEnhancement(String methodName)
+ {
+ return _formatter.format("provided-by-enhancement", methodName);
+ }
}
\ No newline at end of file
1.6 +1 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/BaseComponent.java
Index: BaseComponent.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/BaseComponent.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- BaseComponent.java 6 Feb 2005 15:08:50 -0000 1.5
+++ BaseComponent.java 30 Mar 2005 17:43:33 -0000 1.6
@@ -25,7 +25,7 @@
* @author Howard Lewis Ship
*/
-public abstract class BaseComponent extends AbstractComponent implements ITemplateComponent
+public class BaseComponent extends AbstractComponent implements ITemplateComponent
{
private static final Log LOG = LogFactory.getLog(BaseComponent.class);
1.17 +11 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/AbstractComponent.java
Index: AbstractComponent.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/AbstractComponent.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- AbstractComponent.java 21 Feb 2005 14:01:06 -0000 1.16
+++ AbstractComponent.java 30 Mar 2005 17:43:33 -0000 1.17
@@ -23,6 +23,7 @@
import java.util.Map;
import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.Messages;
import org.apache.hivemind.impl.BaseLocatable;
import org.apache.hivemind.util.Defense;
import org.apache.hivemind.util.PropertyUtils;
@@ -750,4 +751,14 @@
if (_active)
throw new UnsupportedOperationException(TapestryMessages.componentIsLocked(this));
}
+
+ public Messages getMessages()
+ {
+ throw new IllegalStateException(TapestryMessages.providedByEnhancement("getMessages"));
+ }
+
+ public IComponentSpecification getSpecification()
+ {
+ throw new IllegalStateException(TapestryMessages.providedByEnhancement("getSpecification"));
+ }
}
\ No newline at end of file
1.9 +2 -1 jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryStrings2.properties
Index: TapestryStrings2.properties
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/TapestryStrings2.properties,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- TapestryStrings2.properties 29 Mar 2005 13:35:42 -0000 1.8
+++ TapestryStrings2.properties 30 Mar 2005 17:43:33 -0000 1.9
@@ -17,4 +17,5 @@
no-accessor=Component {0} does not have accessor methods for property {1}.
component-is-locked=Component {0} is active and its configuration state may not be changed.
non-unique-attribute=Unable to store {0} into request cycle as attribute ''{1}'' because existing object {2} has already been stored. This usually indicates that components are improperly nested.
-no-page-render-support=No PageRenderSupport object has been stored into the request cycle. This object is typically provided by a Body component. You should add a Body component to your template.
\ No newline at end of file
+no-page-render-support=No PageRenderSupport object has been stored into the request cycle. This object is typically provided by a Body component. You should add a Body component to your template.
+provided-by-enhancement=Method {0}() is not implemented. An implementation of this method should be provided via runtime class enhancement.
\ No newline at end of file
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/TestAbstractComponent.java
Index: TestAbstractComponent.java
===================================================================
// Copyright 2005 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.tapestry;
import org.apache.hivemind.test.HiveMindTestCase;
/**
* Tests a few new features of {@link org.apache.tapestry.AbstractComponent} added in release
* 3.1.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TestAbstractComponent extends HiveMindTestCase
{
private static class ConcreteComponent extends AbstractComponent
{
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
}
}
public void testUnimplementedMethods()
{
IComponent component = new ConcreteComponent();
try
{
component.getMessages();
unreachable();
}
catch (IllegalStateException ex)
{
assertEquals(
"Method getMessages() is not implemented. An implementation of this method should be provided via runtime class enhancement.",
ex.getMessage());
}
try
{
component.getSpecification();
unreachable();
}
catch (IllegalStateException ex)
{
assertEquals(TapestryMessages.providedByEnhancement("getSpecification"), ex
.getMessage());
}
}
}
1.6 +1 -4 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/BasePage.java
Index: BasePage.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/BasePage.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- BasePage.java 22 Mar 2005 13:40:54 -0000 1.5
+++ BasePage.java 30 Mar 2005 17:43:33 -0000 1.6
@@ -21,14 +21,11 @@
* Base class for HTML pages. Most pages should be able to simply subclass this, adding new
* properties and methods. An unlikely exception would be a page that was not based on a template.
* <p>
- * Starting in release 3.1, this class is abstract, as will be any subclasses. This is because the
- * {@link org.apache.tapestry.IComponent#getMessages()}method is abstract, and is filled in at
- * runtime.
*
* @author Howard Lewis Ship
*/
-public abstract class BasePage extends AbstractPage
+public class BasePage extends AbstractPage
{
/**
* @return "text/html"
1.2 +1 -1 jakarta-tapestry/framework/src/test/org/apache/tapestry/components/BaseComponentTestCase.java
Index: BaseComponentTestCase.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/components/BaseComponentTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BaseComponentTestCase.java 21 Feb 2005 14:01:06 -0000 1.1
+++ BaseComponentTestCase.java 30 Mar 2005 17:43:33 -0000 1.2
@@ -41,7 +41,7 @@
protected Object newInstance(Class componentClass)
{
- return getCreator().newInstance(componentClass);
+ return newInstance(componentClass, null);
}
protected Object newInstance(Class componentClass, Object[] properties)
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org