[seam-commits] Seam SVN: r10135 - in trunk/src/wicket/org/jboss/seam/wicket: mock and 1 other directory.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Mon Mar 9 15:27:51 EDT 2009


Author: cpopetz
Date: 2009-03-09 15:27:51 -0400 (Mon, 09 Mar 2009)
New Revision: 10135

Added:
   trunk/src/wicket/org/jboss/seam/wicket/mock/
   trunk/src/wicket/org/jboss/seam/wicket/mock/SeamWicketTester.java
Log:
JBSEAM-3696: Support testing of wicket/seam apps 

Added: trunk/src/wicket/org/jboss/seam/wicket/mock/SeamWicketTester.java
===================================================================
--- trunk/src/wicket/org/jboss/seam/wicket/mock/SeamWicketTester.java	                        (rev 0)
+++ trunk/src/wicket/org/jboss/seam/wicket/mock/SeamWicketTester.java	2009-03-09 19:27:51 UTC (rev 10135)
@@ -0,0 +1,191 @@
+package org.jboss.seam.wicket.mock;
+
+import java.io.File;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.wicket.protocol.http.HttpSessionStore;
+import org.apache.wicket.protocol.http.WebRequestCycle;
+import org.apache.wicket.protocol.http.WebResponse;
+import org.apache.wicket.session.ISessionStore;
+import org.apache.wicket.util.tester.BaseWicketTester;
+import org.apache.wicket.util.tester.DummyHomePage;
+import org.apache.wicket.util.tester.WicketTester;
+import org.jboss.seam.Seam;
+import org.jboss.seam.contexts.Lifecycle;
+import org.jboss.seam.contexts.ServletLifecycle;
+import org.jboss.seam.core.Init;
+import org.jboss.seam.init.Initialization;
+import org.jboss.seam.mock.EmbeddedBootstrap;
+import org.jboss.seam.wicket.SeamWebApplication;
+
+
+/**
+ * A subclass of WicketTester that enforces the use of a SeamWebApplication.  This ensures that
+ * ensures that seam contexts are are set up and torn down correctly in testing.   Each SeamWebApplication
+ * gets a complete application context, so seam application teardown/restart happens if you create
+ * a new SeamWicketTester without propogating any existing SeamWebApplication through the constructor.
+ */
+public class SeamWicketTester extends WicketTester
+{
+
+   public SeamWicketTester()
+   {
+      this(DummyHomePage.class);
+   }
+   
+   public SeamWicketTester(Class homePage) 
+   {
+      this(homePage,null);
+   }
+   
+   public SeamWicketTester(Class homePage, Class loginPage) 
+   {
+      this(createApplication(homePage, loginPage));
+   }
+   
+   public SeamWicketTester(final SeamWebApplication application)
+   {
+      this(application,null);
+   }
+   
+   public SeamWicketTester(final SeamWebApplication application, final String path)
+   {
+      super(application,path);
+      
+      /*
+       * When in tests, we want the contexts destroyed lazily, i.e. 
+       * don't destroy the contexts after a request, but rather before the 
+       * next request, so that we can inspect the values of wicket components and
+       * their models 
+       */
+      Lifecycle.beginCall();
+      ((SeamWebApplication)getApplication()).setDestroyContextsLazily(true);
+      Lifecycle.endCall();
+   }
+
+   /**
+    * Create a SeamWebApplication suitable for testing, a la WicketTester's DummyApplication
+    * @param homePage The WebPage class to start on
+    * @param loginPage The WebPage class to use for any Seam Authentication redirects
+    */
+   private static SeamWebApplication createApplication(final Class homePage, final Class loginPage)
+   {
+      return new SeamWebApplication()
+      {
+         @Override
+         public Class getHomePage()
+         {
+            return homePage;
+         }
+         
+         @Override
+         protected Class getLoginPage()
+         {
+            return loginPage;
+         }
+
+         @Override
+         protected ISessionStore newSessionStore()
+         {
+            // Don't use a filestore, or we spawn lots of threads, which
+            // makes things slow.
+            return new HttpSessionStore(this);
+         }
+
+         @Override
+         protected WebResponse newWebResponse(final HttpServletResponse servletResponse)
+         {
+            // Don't use a buffered response in testing 
+            return new WebResponse(servletResponse);
+         }
+
+         @Override
+         protected void outputDevelopmentModeWarning()
+         {
+            // Do nothing.
+         }
+      };
+   }
+   
+   /**
+    * For each new servletContext, i.e. each new SeamWebApplication instance, we create a new seam
+    * initialization.
+    */
+   @Override
+   public ServletContext newServletContext(String path) 
+   { 
+      if (ServletLifecycle.getServletContext() != null)
+      {
+         ServletLifecycle.endApplication();
+      }
+      if (path == null) 
+      {
+         URL webxml = getClass().getResource("/WEB-INF/web.xml");
+         if (webxml != null)
+         {
+            try
+            {
+               path = new File(webxml.toURI()).getParentFile().getParentFile().getAbsolutePath();
+            }
+            catch (URISyntaxException e)
+            {
+               throw new RuntimeException(e);
+            }
+         }
+      }
+      ServletContext context = super.newServletContext(path);
+      startJbossEmbeddedIfNecessary();
+      ServletLifecycle.beginApplication(context);
+      new Initialization(context).create().init();
+      ((Init) context.getAttribute(Seam.getComponentName(Init.class))).setDebug(false);
+      return context;
+   }
+
+   @Override
+   public WebRequestCycle setupRequestAndResponse(boolean isAjax) { 
+      WebRequestCycle cycle = super.setupRequestAndResponse(isAjax);
+      /**
+       * FormTester wants to walk the form tree and call getValue() on components
+       * without having started the request cycle.  This fails when wicket components have
+       * seam injections.  So force a call here 
+       */
+      BaseWicketTester.callOnBeginRequest(cycle);
+      return cycle;
+   }
+   
+   private static boolean started;
+
+   protected void startJbossEmbeddedIfNecessary() 
+   {
+      try 
+      {
+         if (!started && embeddedJBossAvailable())
+         {
+            new EmbeddedBootstrap().startAndDeployResources();
+         }
+         started = true;
+      }
+      catch (Exception exception)
+      {
+         throw new RuntimeException("Failure starting up Embedded Jboss",exception);
+      }
+   }
+
+   private boolean embeddedJBossAvailable()
+   {
+      try
+      {
+         Class.forName("org.jboss.embedded.Bootstrap");
+         return true;
+      }
+      catch (ClassNotFoundException e)
+      {
+         return false;
+      }
+   }
+
+}




More information about the seam-commits mailing list