You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2006/09/03 17:13:51 UTC

svn commit: r439787 - in /tapestry/tapestry5/tapestry-core/trunk: ./ src/main/java/org/apache/tapestry/internal/services/ src/main/java/org/apache/tapestry/services/ src/test/app1/WEB-INF/ src/test/conf/ src/test/java/org/apache/tapestry/integration/

Author: hlship
Date: Sun Sep  3 08:13:50 2006
New Revision: 439787

URL: http://svn.apache.org/viewvc?rev=439787&view=rev
Log:
Add basic integration tests, driven by Selenium.

Added:
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassFactoryImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/conf/webdefault.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/JettyRunner.java
Modified:
    tapestry/tapestry5/tapestry-core/trunk/pom.xml
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
    tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
    tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/web.xml
    tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml

Modified: tapestry/tapestry5/tapestry-core/trunk/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/pom.xml?rev=439787&r1=439786&r2=439787&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/pom.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/pom.xml Sun Sep  3 08:13:50 2006
@@ -54,6 +54,22 @@
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.openqa.selenium.client-drivers</groupId>
+            <artifactId>selenium-java-client-driver</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.openqa.selenium.server</groupId>
+            <artifactId>selenium-server</artifactId>
+        </dependency>
+        <!-- 
+        <dependency>
+            <groupId>org.mortbay.jetty</groupId>
+            <artifactId>jetty</artifactId>
+            <version>6.0.0beta10</version>
+            <classifier>standalone</classifier>
+            <scope>test</scope>
+        </dependency> -->
     </dependencies>
     <build>
         <plugins>

Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassFactoryImpl.java?rev=439787&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassFactoryImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentClassFactoryImpl.java Sun Sep  3 08:13:50 2006
@@ -0,0 +1,81 @@
+// Copyright 2006 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.internal.services;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.events.InvalidationEvent;
+import org.apache.tapestry.events.InvalidationListener;
+import org.apache.tapestry.internal.ioc.services.ClassFactoryImpl;
+import org.apache.tapestry.ioc.services.ClassFab;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+/**
+ * ClassFactory implementation that works with the class loader created for instantiating
+ * transformed component classes. Works with the
+ * {@link org.apache.tapestry.internal.services.ComponentInstantiatorSource} to handle
+ * {@link org.apache.tapestry.events.InvalidationListener#objectWasInvalidated(InvalidationEvent) invalidations of that class loader}.
+ * 
+ * @author Howard M. Lewis Ship
+ */
+public class ComponentClassFactoryImpl implements ClassFactory, InvalidationListener
+{
+    private final Log _log;
+
+    private final ComponentInstantiatorSource _source;
+
+    private ClassFactory _innerFactory;
+
+    public ComponentClassFactoryImpl(Log log, ComponentInstantiatorSource source)
+    {
+        _log = log;
+        _source = source;
+
+        source.addInvalidationListener(this);
+    }
+
+    private synchronized ClassFactory getInnerFactory()
+    {
+        if (_innerFactory == null)
+            _innerFactory = new ClassFactoryImpl(_source.getClassLoader(), _log);
+
+        return _innerFactory;
+    }
+
+    public ClassLoader getClassLoader()
+    {
+        return getInnerFactory().getClassLoader();
+    }
+
+    public int getCreatedClassCount()
+    {
+        return getInnerFactory().getCreatedClassCount();
+    }
+
+    public ClassFab newClass(Class serviceInterface)
+    {
+        return getInnerFactory().newClass(serviceInterface);
+    }
+
+    public ClassFab newClass(String name, Class superClass)
+    {
+        return getInnerFactory().newClass(name, superClass);
+    }
+
+    public synchronized void objectWasInvalidated(InvalidationEvent event)
+    {
+        _innerFactory = null;
+    }
+
+}

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java?rev=439787&r1=439786&r2=439787&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSource.java Sun Sep  3 08:13:50 2006
@@ -26,7 +26,8 @@
  * loaded classes can be discarded and rebuilt when classes change.
  * <p>
  * The strategy used is that when <em>any</em> class (in a controlled package) changes, the entire
- * class loader is discarded, along with any instances derived from those classes.
+ * class loader is discarded, along with any instances derived from those classes. A new class
+ * loader is created, and then invalidation events are fired to listeners.
  * 
  * @author Howard M. Lewis Ship
  */
@@ -65,4 +66,11 @@
      *            the package name to add (must not be blank)
      */
     void addPackage(String packageName);
+
+    /**
+     * Returns a class loader with visibility to the transformed classes. Caution: callers of this
+     * should also listen for invalidation events and re-acquire the
+     */
+
+    ClassLoader getClassLoader();
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java?rev=439787&r1=439786&r2=439787&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/services/ComponentInstantiatorSourceImpl.java Sun Sep  3 08:13:50 2006
@@ -32,6 +32,7 @@
 import org.apache.tapestry.events.UpdateListener;
 import org.apache.tapestry.internal.event.InvalidationEventHubImpl;
 import org.apache.tapestry.internal.util.URLChangeTracker;
+import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.model.ComponentModel;
 import org.apache.tapestry.util.Defense;
 
@@ -57,6 +58,8 @@
 
     private Loader _loader;
 
+    private ClassFactory _classFactory;
+
     private final ComponentClassTransformer _transformer;
 
     private final Log _log;
@@ -110,8 +113,7 @@
         _instantiatorMap.clear();
 
         // Release the existing class pool, loader and so forth.
-        // Create a new one. Eventually, we need to add notifications
-        // so that existing instances can be released as well.
+        // Create a new one.
 
         initializeService();
 
@@ -119,8 +121,8 @@
     }
 
     /**
-     * Invoked at object crtation, or when there are updates, to create a new set of Javassist class
-     * pools and loaders.
+     * Invoked at object creation, or when there are updates to class files (i.e., invalidation), to
+     * create a new set of Javassist class pools and loaders.
      */
     private void initializeService()
     {

Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=439787&r1=439786&r2=439787&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/services/TapestryModule.java Sun Sep  3 08:13:50 2006
@@ -30,6 +30,7 @@
 import org.apache.tapestry.internal.bindings.LiteralBindingFactory;
 import org.apache.tapestry.internal.services.ApplicationGlobalsImpl;
 import org.apache.tapestry.internal.services.BindingSourceImpl;
+import org.apache.tapestry.internal.services.ComponentClassFactoryImpl;
 import org.apache.tapestry.internal.services.ComponentClassResolverImpl;
 import org.apache.tapestry.internal.services.ComponentInstantiatorSource;
 import org.apache.tapestry.internal.services.HTMLDispatcher;
@@ -55,6 +56,7 @@
 import org.apache.tapestry.ioc.annotations.Lifecycle;
 import org.apache.tapestry.ioc.annotations.SubModule;
 import org.apache.tapestry.ioc.services.ChainBuilder;
+import org.apache.tapestry.ioc.services.ClassFactory;
 import org.apache.tapestry.ioc.services.PipelineBuilder;
 import org.apache.tapestry.ioc.services.PropertyShadowBuilder;
 
@@ -364,5 +366,16 @@
     public void contributeBindingSource(MappedConfiguration<String, BindingFactory> configuration)
     {
         configuration.add(InternalConstants.LITERAL_BINDING_PREFIX, new LiteralBindingFactory());
+    }
+
+    /**
+     * Returns a {@link ClassFactory} that can be used to create extra classes around component
+     * classes.
+     */
+    public ClassFactory buildComponentClassFactory(Log log,
+            @InjectService("tapestry.internal.ComponentInstantiatorSource")
+            ComponentInstantiatorSource source)
+    {
+        return new ComponentClassFactoryImpl(log, source);
     }
 }

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/web.xml?rev=439787&r1=439786&r2=439787&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/web.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/app1/WEB-INF/web.xml Sun Sep  3 08:13:50 2006
@@ -30,6 +30,6 @@
     </filter>
     <filter-mapping>
         <filter-name>app</filter-name>
-        <url-pattern>/</url-pattern>
+        <url-pattern>/*</url-pattern>
     </filter-mapping>
 </web-app>

Modified: tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml?rev=439787&r1=439786&r2=439787&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/conf/testng.xml Sun Sep  3 08:13:50 2006
@@ -36,4 +36,9 @@
       <package name="org.apache.tapestry.internal.model"/>
     </packages>
   </test>
+  <test name="Integration">
+    <packages>
+      <package name="org.apache.tapestry.integration"/>
+    </packages>
+  </test>
 </suite>

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/conf/webdefault.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/conf/webdefault.xml?rev=439787&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/conf/webdefault.xml (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/conf/webdefault.xml Sun Sep  3 08:13:50 2006
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!-- 
+   Copyright 2006 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.
+-->
+
+<web-app 
+   xmlns="http://java.sun.com/xml/ns/j2ee" 
+   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" 
+   version="2.4"> 
+
+  <description>
+    Default web.xml file.  
+    This file is applied to a Web application before it's own WEB_INF/web.xml file
+  </description>
+
+
+
+  <!-- ==================================================================== -->
+  <!-- Context params to control Session Cookies                            -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <!-- UNCOMMENT TO ACTIVATE
+  <context-param>
+    <param-name>org.mortbay.jetty.servlet.SessionDomain</param-name>
+    <param-value>127.0.0.1</param-value>
+  </context-param>
+
+  <context-param>
+    <param-name>org.mortbay.jetty.servlet.SessionPath</param-name>
+    <param-value>/</param-value>
+  </context-param>
+
+  <context-param>
+    <param-name>org.mortbay.jetty.servlet.MaxAge</param-name>
+    <param-value>-1</param-value>
+  </context-param>
+  -->
+
+
+
+  <!-- ==================================================================== -->
+  <!-- The default servlet.                                                 -->
+  <!-- This servlet, normally mapped to /, provides the handling for static -->
+  <!-- content, OPTIONS and TRACE methods for the context.                  -->
+  <!-- The following initParameters are supported:                          -->
+  <!--                                                                      -->
+  <!--   acceptRanges     If true, range requests and responses are         -->
+  <!--                    supported                                         -->
+  <!--                                                                      -->
+  <!--   dirAllowed       If true, directory listings are returned if no    -->
+  <!--                    welcome file is found. Else 403 Forbidden.        -->
+  <!--                                                                      -->
+  <!--   putAllowed       If true, the PUT method is allowed                -->
+  <!--                                                                      -->
+  <!--   delAllowed       If true, the DELETE method is allowed             -->
+  <!--                                                                      -->
+  <!--   redirectWelcome  If true, redirect welcome file requests           -->
+  <!--                    else use request dispatcher forwards              -->
+  <!--                                                                      -->
+  <!--   minGzipLength    If set to a positive integer, then static content -->
+  <!--                    larger than this will be served as gzip content   -->
+  <!--                    encoded if a matching resource is found ending    -->
+  <!--                    with ".gz"                                        -->
+  <!--                                                                      -->
+  <!--   resoureBase      Can be set to replace the context resource base   -->
+  <!--                                                                      -->
+  <!--   relativeResourceBase                                               -->
+  <!--                    Set with a pathname relative to the base of the   -->
+  <!--                    servlet context root. Useful for only serving     -->
+  <!--                    static content from only specific subdirectories. -->
+  <!--                                                                      -->
+  <!-- The MOVE method is allowed if PUT and DELETE are allowed             -->
+  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  -->
+  <servlet>
+    <servlet-name>default</servlet-name>
+    <servlet-class>org.mortbay.jetty.servlet.Default</servlet-class>
+    <init-param>
+      <param-name>acceptRanges</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>dirAllowed</param-name>
+      <param-value>true</param-value>
+    </init-param>
+    <init-param>
+      <param-name>putAllowed</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>delAllowed</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>redirectWelcome</param-name>
+      <param-value>false</param-value>
+    </init-param>
+    <init-param>
+      <param-name>minGzipLength</param-name>
+      <param-value>8192</param-value>
+    </init-param>
+    <load-on-startup>0</load-on-startup>
+  </servlet> 
+
+
+  <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
+
+  <!-- ==================================================================== -->
+  <session-config>
+    <session-timeout>30</session-timeout>
+  </session-config>
+
+
+  <!-- ==================================================================== -->
+  <welcome-file-list>
+    <welcome-file>index.html</welcome-file>
+    <welcome-file>index.htm</welcome-file>
+  </welcome-file-list>
+
+  <!-- ==================================================================== -->
+  <locale-encoding-mapping-list>
+    <locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping>     
+    <locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping>
+    <locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping>   
+  </locale-encoding-mapping-list>
+
+  
+
+</web-app>
+

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=439787&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Sun Sep  3 08:13:50 2006
@@ -0,0 +1,108 @@
+// Copyright 2006 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.integration;
+
+import org.openqa.selenium.server.SeleniumServer;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.thoughtworks.selenium.DefaultSelenium;
+import com.thoughtworks.selenium.Selenium;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+@Test(sequential = true, groups =
+{ "integration" })
+public class IntegrationTests extends Assert
+{
+    private Selenium _selenium;
+
+    private SeleniumServer _server;
+
+    private JettyRunner _jettyRunner;
+
+    public static final String BASE_URL = String.format(
+            "http://localhost:%d",
+            SeleniumServer.DEFAULT_PORT);
+
+    @BeforeClass
+    public void startupBackground() throws Exception
+    {
+        _jettyRunner = new JettyRunner("src/test/app1");
+
+        _server = new SeleniumServer();
+
+        _server.start();
+
+    }
+
+    @BeforeMethod
+    public void setupSelenium()
+    {
+        _selenium = new DefaultSelenium("localhost", SeleniumServer.DEFAULT_PORT, "*firefox",
+                "http://localhost");
+
+        _selenium.start();
+    }
+
+    @AfterMethod
+    public void shutdownSelenim()
+    {
+        _selenium.stop();
+        _selenium = null;
+    }
+
+    @AfterClass
+    public void shutdownBackground() throws Exception
+    {
+        // Thread.sleep(10000);
+
+        _server.stop();
+        _server = null;
+
+        _jettyRunner.stop();
+        _jettyRunner = null;
+    }
+
+    public static final String PAGE_LOAD_TIMEOUT = "1000";
+
+    @Test
+    public void app1_basic_output() throws Exception
+    {
+        _selenium.open("http://localhost/");
+
+        _selenium.click("link=Start Page");
+        _selenium.waitForPageToLoad(PAGE_LOAD_TIMEOUT);
+
+        // This comes from the Border cmponent's template
+
+        assertTrue(_selenium.getTitle().contains("Tapestry"));
+
+        // Text from Start.html
+
+        String body = _selenium.getBodyText();
+
+        assertTrue(body.contains("First Tapestry 5 Page"));
+
+        // This is text passed from Start.html to Output as a parameter
+
+        assertTrue(body.contains("we have basic parameters working"));
+    }
+}

Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/JettyRunner.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/JettyRunner.java?rev=439787&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/JettyRunner.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/integration/JettyRunner.java Sun Sep  3 08:13:50 2006
@@ -0,0 +1,117 @@
+// Copyright 2006 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.integration;
+
+import org.mortbay.http.NCSARequestLog;
+import org.mortbay.http.SocketListener;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.servlet.WebApplicationContext;
+
+import static java.lang.String.format;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class JettyRunner
+{
+    public static final String DEFAULT_CONTEXT_PATH = "/";
+
+    public static final int DEFAULT_PORT = 80;
+
+    private final String _contextPath;
+
+    private final int _port;
+
+    private final String _warPath;
+
+    private final Server _jetty;
+
+    public static void main(String[] args)
+    {
+        new JettyRunner("src/test/app1");
+    }
+
+    /** Defaults the context path to "/" and the port to 80. */
+    public JettyRunner(String warPath)
+    {
+        this(DEFAULT_CONTEXT_PATH, DEFAULT_PORT, warPath);
+    }
+
+    /**
+     * Creates and starts a new instance of Jetty. This should be done from a test case setup
+     * method.
+     * 
+     * @param contextPath
+     *            the context path for the deployed application
+     * @param port
+     *            the port number used to access the application
+     * @param warPath
+     *            the path to the exploded web application (typically, "src/main/webapp")
+     */
+    public JettyRunner(String contextPath, int port, String warPath)
+    {
+        _contextPath = contextPath;
+        _port = port;
+        _warPath = warPath;
+
+        _jetty = createAndStart();
+    }
+
+    /** Stops the Jetty instance. This should be called from a test case tear down method. */
+    public void stop()
+    {
+        try
+        {
+            _jetty.stop();
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException("Error stopping Jetty instance: " + ex.toString(), ex);
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        return format("<JettyRunner %s:%d (%s)>", _contextPath, _port, _warPath);
+    }
+
+    private Server createAndStart()
+    {
+        try
+        {
+            Server server = new Server();
+
+            SocketListener socketListener = new SocketListener();
+            socketListener.setPort(_port);
+            server.addListener(socketListener);
+
+            NCSARequestLog log = new NCSARequestLog();
+            server.setRequestLog(log);
+
+            WebApplicationContext context = server.addWebApplication(_contextPath, _warPath);
+
+            context.setDefaultsDescriptor("src/test/conf/webdefault.xml");
+
+            server.start();
+
+            return server;
+        }
+        catch (Exception ex)
+        {
+            throw new RuntimeException("Failure starting Jetty instance: " + ex.toString(), ex);
+        }
+    }
+}