You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by jk...@apache.org on 2006/07/12 18:30:12 UTC

svn commit: r421307 - in /tapestry/tapestry-test/trunk: ./ .settings/ src/ src/java/ src/java/org/ src/java/org/apache/ src/java/org/apache/tapestry/

Author: jkuhnert
Date: Wed Jul 12 09:30:11 2006
New Revision: 421307

URL: http://svn.apache.org/viewvc?rev=421307&view=rev
Log:
Added new tapestry-test project

Added:
    tapestry/tapestry-test/trunk/.classpath
    tapestry/tapestry-test/trunk/.project
    tapestry/tapestry-test/trunk/.settings/
    tapestry/tapestry-test/trunk/.settings/org.eclipse.jdt.core.prefs
    tapestry/tapestry-test/trunk/pom.xml   (with props)
    tapestry/tapestry-test/trunk/src/
    tapestry/tapestry-test/trunk/src/java/
    tapestry/tapestry-test/trunk/src/java/org/
    tapestry/tapestry-test/trunk/src/java/org/apache/
    tapestry/tapestry-test/trunk/src/java/org/apache/tapestry/
    tapestry/tapestry-test/trunk/src/java/org/apache/tapestry/BaseComponentTestCase.java
Modified:
    tapestry/tapestry-test/trunk/   (props changed)

Propchange: tapestry/tapestry-test/trunk/
------------------------------------------------------------------------------
--- svn:ignore (added)
+++ svn:ignore Wed Jul 12 09:30:11 2006
@@ -0,0 +1,3 @@
+
+bin
+target

Added: tapestry/tapestry-test/trunk/.classpath
URL: http://svn.apache.org/viewvc/tapestry/tapestry-test/trunk/.classpath?rev=421307&view=auto
==============================================================================
--- tapestry/tapestry-test/trunk/.classpath (added)
+++ tapestry/tapestry-test/trunk/.classpath Wed Jul 12 09:30:11 2006
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry path="src/java" kind="src"/>
+	<classpathentry path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER" kind="con"/>
+	<classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>
+	<classpathentry path="bin" kind="output"/>
+</classpath>

Added: tapestry/tapestry-test/trunk/.project
URL: http://svn.apache.org/viewvc/tapestry/tapestry-test/trunk/.project?rev=421307&view=auto
==============================================================================
--- tapestry/tapestry-test/trunk/.project (added)
+++ tapestry/tapestry-test/trunk/.project Wed Jul 12 09:30:11 2006
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>tapestry-test</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.maven.ide.eclipse.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.maven.ide.eclipse.maven2Nature</nature>
+	</natures>
+</projectDescription>

Added: tapestry/tapestry-test/trunk/.settings/org.eclipse.jdt.core.prefs
URL: http://svn.apache.org/viewvc/tapestry/tapestry-test/trunk/.settings/org.eclipse.jdt.core.prefs?rev=421307&view=auto
==============================================================================
--- tapestry/tapestry-test/trunk/.settings/org.eclipse.jdt.core.prefs (added)
+++ tapestry/tapestry-test/trunk/.settings/org.eclipse.jdt.core.prefs Wed Jul 12 09:30:11 2006
@@ -0,0 +1,62 @@
+#Wed Jul 12 12:25:20 EDT 2006
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.5
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nullReference=ignore
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=ignore
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=ignore
+org.eclipse.jdt.core.compiler.source=1.5

Added: tapestry/tapestry-test/trunk/pom.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry-test/trunk/pom.xml?rev=421307&view=auto
==============================================================================
--- tapestry/tapestry-test/trunk/pom.xml (added)
+++ tapestry/tapestry-test/trunk/pom.xml Wed Jul 12 09:30:11 2006
@@ -0,0 +1,258 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tapestry</groupId>
+    <artifactId>tapestry-test</artifactId>
+    <packaging>jar</packaging>
+    <version>4.1.0-SNAPSHOT</version>
+    <description>Tapestry Test Utilities</description>
+    <name>Tapestry Test</name>
+    <inceptionYear>2006</inceptionYear>
+    <url>http://tapestry.apache.org/tapestry-test/</url>
+    
+    <licenses>
+        <license>
+            <name>Apache Software License 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <organization>
+        <name>Apache Software Foundation</name>
+        <url>http://www.apache.org</url>
+    </organization>
+
+    <issueManagement>
+        <system>jira</system>
+        <url>http://issues.apache.org/jira/browse/TAPESTRY</url>
+    </issueManagement>
+
+    <scm>
+        <connection>
+            scm:svn:https://svn.apache.org/repos/asf/tapestry/tapestry-test/trunk
+        </connection>
+        <developerConnection>
+            scm:svn:https://svn.apache.org/repos/asf/tapestry/tapestry-test/trunk/
+        </developerConnection>
+        <url>http://svn.apache.org/viewcvs.cgi/tapestry/tapestry-test/trunk</url>
+    </scm>
+
+    <mailingLists>
+        <mailingList>
+            <name>Tapestry User List</name>
+            <subscribe>tapestry-users-subscribe@tapestry.apache.org</subscribe>
+            <unsubscribe>tapestry-users-unsubscribe@tapestry.apache.org</unsubscribe>
+            <archive>http://mail-archives.apache.org/mod_mbox/tapestry-users/</archive>
+        </mailingList>
+        <mailingList>
+            <name>Tapestry Developer List</name>
+            <subscribe>tapestry-dev-subscribe@tapestry.apache.org</subscribe>
+            <unsubscribe>tapestry-dev-unsubscribe@tapestry.apache.org</unsubscribe>
+            <archive>http://mail-archives.apache.org/mod_mbox/tapestry-dev/</archive>
+        </mailingList>
+        <mailingList>
+            <name>Tapestry Commits List</name>
+            <subscribe>tapestry-commits-subscribe@tapestry.apache.org</subscribe>
+            <unsubscribe>tapestry-commits-unsubscribe@tapestry.apache.org</unsubscribe>
+            <archive>http://mail-archives.apache.org/mod_mbox/tapestry-commits/</archive>
+        </mailingList>
+    </mailingLists>
+
+    <developers>
+        <developer>
+            <id>hls</id>
+            <name>Howard M. Lewis Ship</name>
+            <email>hlship@apache.org</email>
+            <url>http://howardlewisship.com</url>
+            <roles>
+                <role>Menace</role>
+            </roles>
+            <timezone>5</timezone>
+        </developer>
+        <developer>
+            <id>jk</id>
+            <name>Jesse Kuhnert</name>
+            <email>jkuhnert@apache.org</email>
+            <url>http://blog.opencomponentry.com</url>
+            <roles>
+                <role>Developer</role>
+            </roles>
+            <timezone>8</timezone>
+        </developer>
+    </developers>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.tapestry</groupId>
+            <artifactId>tapestry-framework</artifactId>
+            <version>4.1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.0</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>hivemind</groupId>
+            <artifactId>hivemind</artifactId>
+            <version>1.1.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>hivemind</groupId>
+            <artifactId>hivemind-lib</artifactId>
+            <version>1.1.1</version>
+            <scope>compile</scope>
+        </dependency>
+        <!-- Really, a transitive dependency of hivemind. -->
+        <dependency>
+            <groupId>oro</groupId>
+            <artifactId>oro</artifactId>
+            <version>2.0.8</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>1.0.4</version>
+            <!-- This is almost always provided by the container. If not, then WARs will have to
+                create an explicit dependency. -->
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymock</artifactId>
+            <version>2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.easymock</groupId>
+            <artifactId>easymockclassextension</artifactId>
+            <version>2.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+            <version>4.7</version>
+            <classifier>jdk15</classifier>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.3</version>
+        </dependency>
+        <dependency>
+            <groupId>ognl</groupId>
+            <artifactId>ognl</artifactId>
+            <version>2.6.7</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.4</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.javaforge.tapestry</groupId>
+            <artifactId>tapestry-testng</artifactId>
+            <version>0.0.1</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>tapestry</groupId>
+                    <artifactId>tapestry</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <sourceDirectory>src/java</sourceDirectory>
+        <resources>
+            <resource>
+                <directory>src/java</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </resource>
+        </resources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <version>2.1-SNAPSHOT</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-source-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.0</version>
+                <inherited>true</inherited>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <distributionManagement>
+        <site>
+            <id>tapestry</id>
+            <url>scp://apache.org/www/tapestry.apache.org/tapestry-test/</url>
+        </site>
+        <repository>
+            <id>tapestry-repo</id>
+            <url>scp://apache.org/www/www.apache.org/dist/maven-repository</url>
+        </repository>
+        <snapshotRepository>
+            <id>tapestry-snapshot-repo</id>
+            <url>scp://apache.org/www/cvs.apache.org/maven-snapshot-repository</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+    <repositories>
+        <repository>
+            <id>apache.snapshots</id>
+            <url>http://people.apache.org/maven-snapshot-repository</url>
+        </repository>
+        <repository>
+            <id>tapestry.javaforge</id>
+            <url>http://howardlewisship.com/repository</url>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>apache.snapshots</id>
+            <url>http://people.apache.org/maven-snapshot-repository</url>
+        </pluginRepository>
+        <pluginRepository>
+            <id>tapestry.javaforge</id>
+            <url>http://howardlewisship.com/repository</url>
+        </pluginRepository>
+    </pluginRepositories>
+
+</project>
\ No newline at end of file

Propchange: tapestry/tapestry-test/trunk/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: tapestry/tapestry-test/trunk/src/java/org/apache/tapestry/BaseComponentTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry-test/trunk/src/java/org/apache/tapestry/BaseComponentTestCase.java?rev=421307&view=auto
==============================================================================
--- tapestry/tapestry-test/trunk/src/java/org/apache/tapestry/BaseComponentTestCase.java (added)
+++ tapestry/tapestry-test/trunk/src/java/org/apache/tapestry/BaseComponentTestCase.java Wed Jul 12 09:30:11 2006
@@ -0,0 +1,627 @@
+package org.apache.tapestry;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.checkOrder;
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertTrue;
+
+import java.io.CharArrayWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.commons.logging.Log;
+import org.apache.hivemind.ClassResolver;
+import org.apache.hivemind.Locatable;
+import org.apache.hivemind.Location;
+import org.apache.hivemind.ModuleDescriptorProvider;
+import org.apache.hivemind.Registry;
+import org.apache.hivemind.Resource;
+import org.apache.hivemind.impl.DefaultClassResolver;
+import org.apache.hivemind.impl.RegistryBuilder;
+import org.apache.hivemind.impl.XmlModuleDescriptorProvider;
+import org.apache.hivemind.test.HiveMindTestCase;
+import org.apache.hivemind.util.URLResource;
+import org.apache.tapestry.components.ILinkComponent;
+import org.apache.tapestry.engine.IEngineService;
+import org.apache.tapestry.engine.ILink;
+import org.apache.tapestry.engine.NullWriter;
+import org.apache.tapestry.event.BrowserEvent;
+import org.apache.tapestry.json.IJSONWriter;
+import org.apache.tapestry.markup.AsciiMarkupFilter;
+import org.apache.tapestry.markup.JSONWriterImpl;
+import org.apache.tapestry.markup.MarkupWriterImpl;
+import org.apache.tapestry.services.ResponseBuilder;
+import org.apache.tapestry.services.impl.DefaultResponseBuilder;
+import org.apache.tapestry.spec.IComponentSpecification;
+import org.apache.tapestry.spec.IParameterSpecification;
+import org.apache.tapestry.test.Creator;
+import org.apache.tapestry.web.WebRequest;
+
+import com.javaforge.tapestry.testng.TestBase;
+
+/**
+ * Base class for testing components, or testing classes that operate on components. Simplifies
+ * creating much of the infrastructure around the components.
+ * <p>
+ * This class may eventually be part of the Tapestry distribution.
+ * 
+ * @author Howard M. Lewis Ship
+ * @since 4.0
+ */
+public class BaseComponentTestCase extends TestBase
+{
+    private Creator _creator;
+
+    protected Creator getCreator()
+    {
+        if (_creator == null)
+            _creator = new Creator();
+        
+        return _creator;
+    }
+
+    protected ClassResolver getClassResolver()
+    {
+        return new DefaultClassResolver();
+    }
+    
+    protected CharArrayWriter _charArrayWriter;
+
+    protected IMarkupWriter newBufferWriter()
+    {
+        _charArrayWriter = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(_charArrayWriter);
+
+        return new MarkupWriterImpl("text/html", pw, new AsciiMarkupFilter());
+    }
+    
+    protected IJSONWriter newBufferJSONWriter()
+    {
+        _charArrayWriter = new CharArrayWriter();
+        PrintWriter pw = new PrintWriter(_charArrayWriter);
+        
+        return new JSONWriterImpl(pw);
+    }
+    
+    protected void assertBuffer(String expected)
+    {
+        String actual = _charArrayWriter.toString();
+
+        assertEquals("Buffered markup writer content.", expected, actual);
+
+        _charArrayWriter.reset();
+    }
+
+    protected void assertExceptionSubstring(Throwable t, String msg)
+    {
+        assertTrue(t.getMessage().contains(msg));
+    }
+    
+    protected Object newInstance(Class componentClass)
+    {
+        return newInstance(componentClass, null);
+    }
+
+    protected Object newInstance(Class componentClass, String propertyName, Object propertyValue)
+    {
+        return getCreator().newInstance(componentClass, new Object[]
+        { propertyName, propertyValue });
+    }
+
+    protected IRequestCycle newCycle()
+    {
+        return newMock(IRequestCycle.class);
+    }
+
+    protected IRequestCycle newCycle(IMarkupWriter writer)
+    {
+        IRequestCycle cycle = newMock(IRequestCycle.class);
+        
+        trainResponseBuilder(cycle, writer);
+        
+        return cycle;
+    }
+    
+    protected IRequestCycle newCycle(boolean rewinding)
+    {
+        return newCycle(rewinding, null);
+    }
+    
+    protected IRequestCycle newCycle(boolean rewinding, boolean trainWriter)
+    {
+        IRequestCycle cycle = newRequestCycle();
+        
+        trainIsRewinding(cycle, rewinding);
+        
+        if (trainWriter)
+            trainResponseBuilder(cycle, null);
+        
+        return cycle;
+    }
+    
+    protected IRequestCycle newCycle(boolean rewinding, IMarkupWriter writer)
+    {
+        IRequestCycle cycle = newRequestCycle();
+        checkOrder(cycle, false);
+        
+        trainIsRewinding(cycle, rewinding);
+        
+        if (writer != null)
+            trainResponseBuilder(cycle, writer);
+        
+        return cycle;
+    }
+    
+    protected void trainResponseBuilder(IRequestCycle cycle, IMarkupWriter writer)
+    {
+        ResponseBuilder builder = 
+            new DefaultResponseBuilder(writer == null ? NullWriter.getSharedInstance() : writer);
+        
+        expect(cycle.getResponseBuilder()).andReturn(builder);
+    }
+    
+    protected void trainIsRewinding(IRequestCycle cycle, boolean rewinding)
+    {
+        expect(cycle.isRewinding()).andReturn(rewinding);
+    }
+
+    protected IRequestCycle newCycleGetPage(String pageName, IPage page)
+    {
+        IRequestCycle cycle = newRequestCycle();
+
+        expect(cycle.getPage(pageName)).andReturn(page);
+
+        return cycle;
+    }
+
+    protected IRequestCycle newCycleGetUniqueId(String id, String uniqueId)
+    {
+        IRequestCycle cycle = newRequestCycle();
+
+        expect(cycle.getUniqueId(id)).andReturn(uniqueId);
+        return cycle;
+    }
+
+    protected IRequestCycle newCycleGetParameter(String name, String value)
+    {
+        IRequestCycle cycle = newRequestCycle();
+
+        expect(cycle.getParameter(name)).andReturn(value);
+        return cycle;
+    }
+
+    protected IMarkupWriter newWriter()
+    {
+        return newMock(IMarkupWriter.class);
+    }
+
+    protected IBinding newBinding(Object value)
+    {
+        IBinding binding = newMock(IBinding.class);
+        checkOrder(binding, false);
+        
+        expect(binding.getObject()).andReturn(value);
+        return binding;
+    }
+
+    protected IBinding newBinding(Location location)
+    {
+        IBinding binding = newBinding();
+        checkOrder(binding, false);
+        
+        trainGetLocation(binding, location);
+
+        return binding;
+    }
+
+    protected IComponent newComponent(String extendedId, Location location)
+    {
+        IComponent component = newMock(IComponent.class);
+        checkOrder(component, false);
+        
+        expect(component.getExtendedId()).andReturn(extendedId);
+        expect(component.getLocation()).andReturn(location);
+        return component;
+    }
+
+    protected IComponentSpecification newSpec(String parameterName, IParameterSpecification pspec)
+    {
+        IComponentSpecification spec = newMock(IComponentSpecification.class);
+
+        expect(spec.getParameter(parameterName)).andReturn(pspec);
+        return spec;
+    }
+
+    protected IRender newRender()
+    {
+        return newMock(IRender.class);
+    }
+
+    protected IPage newPage()
+    {
+        return newMock(IPage.class);
+    }
+
+    protected IPage newPage(String name)
+    {
+        return newPage(name, 1);
+    }
+
+    protected IPage newPage(String name, int count)
+    {
+        IPage page = newMock(IPage.class);
+        checkOrder(page, false);
+        
+        expect(page.getPageName()).andReturn(name).times(count);
+        
+        return page;
+    }
+
+    protected IForm newForm()
+    {
+        return newMock(IForm.class);
+    }
+
+    protected IRender newBody()
+    {
+        return new IRender()
+        {
+            public void render(IMarkupWriter writer, IRequestCycle cycle)
+            {
+                writer.print("BODY");
+            }
+        };
+    }
+
+    protected PageRenderSupport newPageRenderSupport()
+    {
+        return newMock(PageRenderSupport.class);
+    }
+
+    protected void trainGetSupport(IRequestCycle cycle, PageRenderSupport support)
+    {
+        trainGetAttribute(cycle, TapestryUtils.PAGE_RENDER_SUPPORT_ATTRIBUTE, support);
+    }
+
+    protected void trainGetAttribute(IRequestCycle cycle, String attributeName, Object attribute)
+    {
+        expect(cycle.getAttribute(attributeName)).andReturn(attribute);
+    }
+
+    protected void trainGetUniqueId(IRequestCycle cycle, String id, String uniqueId)
+    {
+        expect(cycle.getUniqueId(id)).andReturn(uniqueId);
+    }
+
+    protected void trainGetIdPath(IComponent component, String idPath)
+    {
+        expect(component.getIdPath()).andReturn(idPath);
+    }
+
+    protected void trainGetParameter(IRequestCycle cycle, String name, String value)
+    {
+        expect(cycle.getParameter(name)).andReturn(value);
+    }
+
+    protected void trainGetPageName(IPage page, String pageName)
+    {
+        expect(page.getPageName()).andReturn(pageName);
+    }
+
+    protected void trainBuildURL(IAsset asset, IRequestCycle cycle, String URL)
+    {
+        expect(asset.buildURL()).andReturn(URL);
+    }
+
+    protected IAsset newAsset()
+    {
+        return newMock(IAsset.class);
+    }
+
+    protected IEngine newEngine(ClassResolver resolver)
+    {
+        IEngine engine = newMock(IEngine.class);
+        
+        return engine;
+    }
+
+    protected void trainGetEngine(IPage page, IEngine engine)
+    {
+        expect(page.getEngine()).andReturn(engine);
+    }
+
+    protected IComponent newComponent()
+    {
+        return newMock(IComponent.class);
+    }
+
+    protected void trainGetPage(IComponent component, IPage page)
+    {
+        expect(component.getPage()).andReturn(page);
+    }
+
+    protected void trainGetExtendedId(IComponent component, String extendedId)
+    {
+        expect(component.getExtendedId()).andReturn(extendedId);
+    }
+
+    protected void trainGetLocation(Locatable locatable, Location location)
+    {
+        expect(locatable.getLocation()).andReturn(location);
+    }
+
+    protected IBinding newBinding()
+    {
+        return newMock(IBinding.class);
+    }
+
+    protected void trainGetComponent(IComponent container, String componentId, IComponent containee)
+    {
+        expect(container.getComponent(componentId)).andReturn(containee);
+    }
+
+    protected IEngineService newEngineService()
+    {
+        return newMock(IEngineService.class);
+    }
+
+    protected void trainGetLink(IEngineService service, IRequestCycle cycle, boolean post,
+            Object parameter, ILink link)
+    {
+        expect(service.getLink(post, parameter)).andReturn(link);
+    }
+
+    protected void trainGetLinkCheckIgnoreParameter(IEngineService service, IRequestCycle cycle,
+            boolean post, Object parameter, ILink link)
+    {
+        expect(service.getLink(eq(post), anyObject())).andReturn(link);
+    }
+
+    protected void trainGetURL(ILink link, String URL)
+    {
+        expect(link.getURL()).andReturn(URL);
+    }
+
+    protected void trainGetPageRenderSupport(IRequestCycle cycle, PageRenderSupport support)
+    {
+        trainGetAttribute(cycle, TapestryUtils.PAGE_RENDER_SUPPORT_ATTRIBUTE, support);
+    }
+
+    protected IComponentSpecification newSpec()
+    {
+        return newMock(IComponentSpecification.class);
+    }
+
+    protected Resource newResource()
+    {
+        return newMock(Resource.class);
+    }
+
+    protected WebRequest newRequest()
+    {
+        return newMock(WebRequest.class);
+    }
+
+    protected Location newLocation()
+    {
+        return newMock(Location.class);
+    }
+    
+    protected Location fabricateLocation(int line)
+    {
+        Location location = newLocation();
+        checkOrder(location, false);
+        
+        expect(location.getLineNumber()).andReturn(line).anyTimes();
+        
+        return location;
+    }
+    
+    protected void trainEncodeURL(IRequestCycle rc, String URL, String encodedURL)
+    {
+        expect(rc.encodeURL(URL)).andReturn(encodedURL);
+    }
+
+    protected void trainGetServerPort(WebRequest request, int port)
+    {
+        expect(request.getServerPort()).andReturn(port);
+    }
+
+    protected void trainGetServerName(WebRequest request, String serverName)
+    {
+        expect(request.getServerName()).andReturn(serverName);
+    }
+
+    protected void trainGetScheme(WebRequest request, String scheme)
+    {
+        expect(request.getScheme()).andReturn(scheme);
+    }
+
+    protected NestedMarkupWriter newNestedWriter()
+    {
+        return newMock(NestedMarkupWriter.class);
+    }
+
+    protected void trainGetNestedWriter(IMarkupWriter writer, NestedMarkupWriter nested)
+    {
+        expect(writer.getNestedWriter()).andReturn(nested);
+    }
+    
+    protected void trainGetURL(ILink link, String scheme, String anchor, String URL)
+    {
+        trainGetURL(link, scheme, anchor, URL, 0);
+    }
+    
+    protected void trainGetURL(ILink link, String scheme, String anchor, String URL, int port)
+    {
+        expect(link.getURL(scheme, null, port, anchor, true)).andReturn(URL);
+    }
+
+    protected ILink newLink()
+    {
+        return newMock(ILink.class);
+    }
+
+    protected void trainGetLink(ILinkComponent component, IRequestCycle cycle, ILink link)
+    {
+        expect(component.getLink(cycle)).andReturn(link);
+    }
+
+    protected void trainGetEngine(IRequestCycle cycle, IEngine engine)
+    {
+        expect(cycle.getEngine()).andReturn(engine);
+    }
+
+    protected void trainGetParameterValues(ILink link, String parameterName, String[] values)
+    {
+        expect(link.getParameterValues(parameterName)).andReturn(values);
+    }
+
+    protected void trainGetParameterNames(ILink link, String[] names)
+    {
+        expect(link.getParameterNames()).andReturn(names);
+    }
+
+    protected void trainGetSpecification(IComponent component, IComponentSpecification spec)
+    {
+        expect(component.getSpecification()).andReturn(spec);
+    }
+
+    protected void trainGetBinding(IComponent component, String name, IBinding binding)
+    {
+        expect(component.getBinding(name)).andReturn(binding);
+    }
+
+    protected Log newLog()
+    {
+        return newMock(Log.class);
+    }
+
+    protected void trainGetId(IComponent component, String id)
+    {
+        expect(component.getId()).andReturn(id);
+    }
+    
+    protected void trainExtractBrowserEvent(IRequestCycle cycle)
+    {
+        expect(cycle.getParameter(BrowserEvent.NAME)).andReturn("onClick").anyTimes();
+        
+        expect(cycle.getParameter(BrowserEvent.TYPE)).andReturn("click");
+        expect(cycle.getParameters(BrowserEvent.KEYS)).andReturn(null);
+        expect(cycle.getParameter(BrowserEvent.CHAR_CODE)).andReturn(null);
+        expect(cycle.getParameter(BrowserEvent.PAGE_X)).andReturn("123");
+        expect(cycle.getParameter(BrowserEvent.PAGE_Y)).andReturn("1243");
+        expect(cycle.getParameter(BrowserEvent.LAYER_X)).andReturn(null);
+        expect(cycle.getParameter(BrowserEvent.LAYER_Y)).andReturn(null);
+        
+        expect(cycle.getParameter(BrowserEvent.TARGET + "." + BrowserEvent.TARGET_ATTR_ID))
+        .andReturn("element1");
+    }
+    
+    /**
+     * Convienience method for invoking {@link #buildFrameworkRegistry(String[])} with only a single
+     * file.
+     */
+    protected Registry buildFrameworkRegistry(String file) throws Exception
+    {
+        return buildFrameworkRegistry(new String[]
+        { file });
+    }
+    
+    /**
+     * Builds a minimal registry, containing only the specified files, plus the master module
+     * descriptor (i.e., those visible on the classpath). Files are resolved using
+     * {@link HiveMindTestCase#getResource(String)}.
+     */
+    protected Registry buildFrameworkRegistry(String[] files) throws Exception
+    {
+        ClassResolver resolver = getClassResolver();
+
+        List descriptorResources = new ArrayList();
+        for (int i = 0; i < files.length; i++)
+        {
+            Resource resource = getResource(files[i]);
+
+            descriptorResources.add(resource);
+        }
+
+        ModuleDescriptorProvider provider = new XmlModuleDescriptorProvider(resolver,
+                descriptorResources);
+
+        return buildFrameworkRegistry(provider);
+    }
+    
+    /**
+     * Builds a registry, containing only the modules delivered by the specified
+     * {@link org.apache.hivemind.ModuleDescriptorProvider}, plus the master module descriptor
+     * (i.e., those visible on the classpath).
+     */
+    protected Registry buildFrameworkRegistry(ModuleDescriptorProvider customProvider)
+    {
+        ClassResolver resolver = getClassResolver();
+
+        RegistryBuilder builder = new RegistryBuilder();
+
+        builder.addModuleDescriptorProvider(new XmlModuleDescriptorProvider(resolver));
+        builder.addModuleDescriptorProvider(customProvider);
+
+        return builder.constructRegistry(Locale.getDefault());
+    }
+
+    /**
+     * Builds a registry from exactly the provided resource; this registry will not include the
+     * <code>hivemind</code> module.
+     */
+    protected Registry buildMinimalRegistry(Resource l) throws Exception
+    {
+        RegistryBuilder builder = new RegistryBuilder();
+
+        return builder.constructRegistry(Locale.getDefault());
+    }
+    
+    /**
+     * Returns the given file as a {@link Resource} from the classpath. Typically, this is to find
+     * files in the same folder as the invoking class.
+     */
+    protected Resource getResource(String file)
+    {
+        URL url = getClass().getResource(file);
+
+        if (url == null)
+            throw new NullPointerException("No resource named '" + file + "'.");
+
+        return new URLResource(url);
+    }
+    
+    public static boolean assertListEquals(Object[] expected, Object[] actual)
+    {
+        if (expected == null || actual == null)
+            notEquals(expected, actual);
+        
+        if (!Arrays.equals(expected, actual))
+            notEquals(expected, actual);
+        
+        return true;
+    }
+    
+    public static boolean assertListEquals(Object[] expected, List actual)
+    {
+        if (expected == null || actual == null)
+            notEquals(expected, actual);
+        
+        Object[] acarr = actual.toArray(new Object[actual.size()]);
+        return assertListEquals(expected, acarr);
+    }
+    
+    public static void notEquals(Object expected, Object actual)
+    {
+        throw new AssertionError("Parameters don't match, expected: <"
+                + expected + "> actual: <" + actual + ">");
+    }
+}
\ No newline at end of file