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}&nbsp;and
  + * {@link org.apache.tapestry.IComponent#getMessages() messages}&nbsp;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}&nbsp;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