You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2011/10/26 23:34:02 UTC

svn commit: r1189484 - in /myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc: ./ test/ test/core/

Author: lu4242
Date: Wed Oct 26 21:34:01 2011
New Revision: 1189484

URL: http://svn.apache.org/viewvc?rev=1189484&view=rev
Log:
MYFACES-3376 Create abstract test classes that runs MyFaces Core as in a container

Added:
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesFaceletsTestCase.java   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesRequestTestCase.java   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguage.java   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguageStrategy.java   (with props)
    myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesViewDeclarationLanguageFactory.java   (with props)

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/
------------------------------------------------------------------------------
    bugtraq:number = true

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/
------------------------------------------------------------------------------
    bugtraq:number = true

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/
------------------------------------------------------------------------------
    bugtraq:number = true

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesFaceletsTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesFaceletsTestCase.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesFaceletsTestCase.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesFaceletsTestCase.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import javax.faces.FactoryFinder;
+import javax.faces.component.UIViewRoot;
+import javax.faces.view.ViewDeclarationLanguageFactory;
+
+/**
+ * <p>Abstract JUnit test case base class, which provide a var called vdl, that
+ * can be used to build facelet views calling for example:</p>
+ * <p>vdl.buildView(facesContext, facesContext.getViewRoot(), "/hello.xhtml");</p>
+ * <p>It already set up a request.</p>
+ * 
+ * @author Leonardo Uribe
+ *
+ */
+public abstract class AbstractMyFacesFaceletsTestCase extends AbstractMyFacesRequestTestCase
+{
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        
+        setupFaceletRequest();
+
+        setUpVDL();
+    }
+    
+    protected void setUpVDL() throws Exception
+    {
+        ViewDeclarationLanguageFactory vdlFactory = (ViewDeclarationLanguageFactory) FactoryFinder.getFactory(FactoryFinder.VIEW_DECLARATION_LANGUAGE_FACTORY);
+        vdl = (MockMyFacesFaceletViewDeclarationLanguage) vdlFactory.getViewDeclarationLanguage("/a.xhtml");
+    }
+    
+    protected void setupFaceletRequest() throws Exception
+    {
+        setupRequest();
+        // Create a new UIViewRoot to work with it later
+        UIViewRoot root = new UIViewRoot();
+        root.setViewId("/test");
+        root.setRenderKitId("HTML_BASIC");
+        facesContext.setViewRoot(root);
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        tearDownRequest();
+        
+        super.tearDown();
+    }
+    
+    protected MockMyFacesFaceletViewDeclarationLanguage vdl;
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesFaceletsTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesRequestTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesRequestTestCase.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesRequestTestCase.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesRequestTestCase.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,221 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import javax.faces.application.Application;
+import javax.faces.component.UICommand;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIInput;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.test.mock.MockHttpServletRequest;
+import org.apache.myfaces.test.mock.MockHttpServletResponse;
+import org.apache.myfaces.test.mock.MockHttpSession;
+
+/**
+ * <p>Abstract JUnit test case base class, with method to setup/teardown a request.
+ * It helps to create tests that involve multiple requests like client submits, or
+ * tests that involve more control over the lifecycle.</p>
+ * 
+ * 
+ * @author Leonardo Uribe
+ *
+ */
+public abstract class AbstractMyFacesRequestTestCase extends AbstractMyFacesTestCase
+{
+    
+    @Override
+    public void setUp() throws Exception
+    {
+        super.setUp();
+        
+    }
+
+    @Override
+    public void tearDown() throws Exception
+    {
+        tearDownRequest();
+        session = null;
+        client = null;
+        super.tearDown();
+    }
+
+    protected void setupRequest() throws Exception
+    {
+        setupRequest(null);
+    }
+
+    protected void setupRequest(String pathInfo) throws Exception
+    {
+        if (pathInfo == null)
+        {
+            setupRequest(null, null);
+        }
+        else
+        {
+            int queryIndex = pathInfo.indexOf("?");
+            if (queryIndex >= 0) 
+            {
+                setupRequest(pathInfo.substring(0,queryIndex), pathInfo.substring(queryIndex+1));
+            }
+            else
+            {
+                setupRequest(pathInfo, null);
+            }
+        }
+    }
+    
+    protected void setupRequest(String pathInfo, String query) throws Exception
+    {
+        session = (session == null) ? new MockHttpSession() : session;
+        session.setServletContext(servletContext);
+        request = new MockHttpServletRequest(session);
+        request.setServletContext(servletContext);
+        response = new MockHttpServletResponse();
+        //TODO check if this is correct
+        request.setPathElements(getContextPath(), getServletPath(), pathInfo, query);
+
+        facesContext = facesContextFactory.getFacesContext(servletContext, request, response, lifecycle);
+        externalContext = facesContext.getExternalContext();
+        application = facesContext.getApplication();
+        if (client != null)
+        {
+            client.apply(request);
+        }
+        //Reset client
+        client = createClient();
+    }
+    
+    protected MockMyFacesClient createClient()
+    {
+        return new MockMyFacesClient(facesContext);
+    }
+    
+    protected void tearDownRequest()
+    {
+        if (facesContext != null)
+        {
+            facesContext.release();
+        }
+        facesContext = null;
+        externalContext = null;
+        application = null;
+        
+        response = null;
+        request = null;
+        //session = null;
+    }
+    
+    protected String getContextPath()
+    {
+        return "/test";
+    }
+    
+    protected String getServletPath()
+    {
+        return "/faces";
+    }
+
+    protected void processLifecycleExecute() throws Exception
+    {
+        processLifecycleExecute(facesContext);
+    }
+    
+    protected void processLifecycleExecuteAndRender() throws Exception
+    {
+        processLifecycleExecute();
+        processRender();
+    }
+
+    protected void processRestoreViewPhase() throws Exception
+    {
+        processRestoreViewPhase(facesContext);
+    }
+    
+    protected void processApplyRequestValuesPhase() throws Exception
+    {
+        processApplyRequestValuesPhase(facesContext);
+    }
+
+    protected void processValidationsPhase() throws Exception
+    {
+        processValidationsPhase(facesContext);
+    }
+
+    protected void processUpdateModelPhase() throws Exception
+    {
+        processUpdateModelPhase(facesContext);
+
+    }
+    
+    protected void processInvokeApplicationPhase() throws Exception
+    {
+        processInvokeApplicationPhase(facesContext);
+    }
+    
+    protected void processRender() throws Exception
+    {
+        processRender(facesContext);
+    }
+    
+    protected void processRemainingExecutePhases() throws Exception
+    {
+        processRemainingExecutePhases(facesContext);
+    }
+
+    protected void processRemainingPhases() throws Exception
+    {
+        processRemainingPhases(facesContext);
+    }
+    
+    protected void inputText(UIComponent input, String text)
+    {
+        client.inputText((UIInput)input, text);
+    }
+    
+    /**
+     * Simulate a submit, processing the remaining phases and setting up the new request.
+     * It delegates to client.submit, where the necessary data is gathered to be applied
+     * later on client.apply method.
+     * 
+     * @param component
+     * @throws Exception
+     */
+    protected void submit(UIComponent component) throws Exception
+    {
+        processRemainingPhases();
+        client.submit((UICommand)component);
+        String viewId = facesContext.getViewRoot().getViewId();
+        tearDownRequest();
+        setupRequest(viewId);
+    }
+
+    protected MockMyFacesClient client = null;
+    
+    // Servlet objects 
+    protected MockHttpServletRequest request = null;
+    protected MockHttpServletResponse response = null;
+    protected MockHttpSession session = null;
+    
+    protected Application application = null;
+    protected ExternalContext externalContext = null;
+    protected FacesContext facesContext = null;
+
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesRequestTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,656 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import java.io.FileNotFoundException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+
+import javax.el.ExpressionFactory;
+import javax.faces.FactoryFinder;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.context.FacesContextFactory;
+import javax.faces.event.PhaseId;
+import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
+import javax.faces.webapp.FacesServlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+import org.apache.myfaces.config.DefaultFacesConfigurationProvider;
+import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.config.element.FacesConfig;
+import org.apache.myfaces.config.impl.digester.elements.Factory;
+import org.apache.myfaces.lifecycle.LifecycleImpl;
+import org.apache.myfaces.spi.FacesConfigurationProvider;
+import org.apache.myfaces.spi.impl.DefaultFacesConfigurationProviderFactory;
+import org.apache.myfaces.test.el.MockExpressionFactory;
+import org.apache.myfaces.test.mock.MockServletConfig;
+import org.apache.myfaces.test.mock.MockServletContext;
+import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
+import org.apache.myfaces.webapp.AbstractFacesInitializer;
+import org.apache.myfaces.webapp.StartupServletContextListener;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * <p>Abstract JUnit test case base class, which sets up MyFaces Core environment
+ * using mock object for the outer servlet environment.</p>
+ * <p>Since jsp engine is not bundled with MyFaces, this configuration is able to 
+ * handle facelet pages only.</p>
+ * 
+ * @author Leonardo Uribe
+ *
+ */
+public abstract class AbstractMyFacesTestCase
+{
+    private static Class<?> PHASE_EXECUTOR_CLASS = null;
+    private static Class<?> PHASE_MANAGER_CLASS = null;
+    
+    static {
+        try
+        {
+            PHASE_EXECUTOR_CLASS = Class.forName("org.apache.myfaces.lifecycle.PhaseExecutor");
+            PHASE_MANAGER_CLASS = Class.forName("org.apache.myfaces.lifecycle.PhaseListenerManager");
+        }
+        catch (ClassNotFoundException e)
+        {
+            //No op
+        }
+    }
+    
+    public static final String PHASE_MANAGER_INSTANCE = "org.apache.myfaces.test.PHASE_MANAGER_INSTANCE";
+    
+    public static final String LAST_PHASE_PROCESSED = "oam.LAST_PHASE_PROCESSED";
+    
+    // ------------------------------------------------------------ Constructors
+
+    /**
+     * <p>Construct a new instance of this test case.</p>
+     *
+     * @param name Name of this test case
+     */    
+    public AbstractMyFacesTestCase()
+    {
+    }
+
+    // ---------------------------------------------------- Overall Test Methods
+
+    /**
+     * <p>Set up instance variables required by this test case.</p>
+     */
+    @Before
+    public void setUp() throws Exception
+    {
+        // Set up a new thread context class loader
+        threadContextClassLoader = Thread.currentThread()
+                .getContextClassLoader();
+        Thread.currentThread()
+                .setContextClassLoader(
+                        new URLClassLoader(new URL[0], this.getClass()
+                                .getClassLoader()));
+
+        // Set up Servlet API Objects
+        setUpServletObjects();
+
+        // Set up JSF API Objects
+        FactoryFinder.releaseFactories();
+
+        setUpServletListeners();
+        
+        setUpFacesServlet();
+    }
+    
+    /**
+     * <p>Setup servlet objects that will be used for the test:</p>
+     * 
+     * <ul>
+     * <li><code>servletConfig</code> (<code>MockServletConfig</code>)</li>
+     * <li><code>servletContext</code> (<code>MockServletContext</code>)</li>
+     * </ul>
+     * 
+     * @throws Exception
+     */
+    protected void setUpServletObjects() throws Exception
+    {
+        servletContext = new MockServletContext();
+        servletConfig = new MockServletConfig(servletContext);
+        servletContext.setDocumentRoot(getWebappContextURI());
+        setUpWebConfigParams();
+    }
+    
+    /**
+     * <p>Setup web config params. By default it sets the following params</p>
+     * 
+     * <ul>
+     * <li>"org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE", "true"</li>
+     * <li>"javax.faces.PROJECT_STAGE", "UnitTest"</li>
+     * <li>"javax.faces.PARTIAL_STATE_SAVING", "true"</li>
+     * <li>"javax.faces.FACELETS_REFRESH_PERIOD", "-1"</li>
+     * </ul>
+     * 
+     * @throws Exception
+     */
+    protected void setUpWebConfigParams() throws Exception
+    {
+        servletContext.addInitParameter("org.apache.myfaces.INITIALIZE_ALWAYS_STANDALONE", "true");
+        servletContext.addInitParameter("javax.faces.PROJECT_STAGE", "UnitTest");
+        servletContext.addInitParameter("javax.faces.PARTIAL_STATE_SAVING", "true");
+        servletContext.addInitParameter(FaceletViewDeclarationLanguage.PARAM_REFRESH_PERIOD,"-1");
+    }
+    
+    /**
+     * <p>Return an URI that identifies the base path that will be used by servletContext
+     * to load resources like facelet files an others. By default it points to the directory
+     * path calculated from the package name of the child test class.</p>
+     * 
+     * @return
+     */
+    protected URI getWebappContextURI()
+    {
+        try
+        {
+            ClassLoader cl = Thread.currentThread().getContextClassLoader();
+            URL url = cl.getResource(getWebappContextFilePath());
+            if (url == null)
+            {
+                throw new FileNotFoundException(cl.getResource("").getFile()
+                        + getWebappContextFilePath() + " was not found");
+            }
+            else
+            {
+                return new URI(url.toString());
+            }
+        }
+        catch (Exception e)
+        {
+            throw new RuntimeException("Error Initializing Context", e);
+        }
+    }
+    
+    /**
+     * Return a path that is used to load resources like facelet files an others.
+     * By default it points to the directory path calculated from the package 
+     * name of the child test class.
+     * 
+     * @return
+     */
+    protected String getWebappContextFilePath()
+    {
+        return this.getClass().getName().substring(0,
+                this.getClass().getName().lastIndexOf('.')).replace('.', '/')
+                + "/";
+    }
+    
+    /**
+     * Create the ExpressionFactory instance that will be used to initialize the test
+     * environment. By default it uses MockExpressionFactory. 
+     * 
+     * @return
+     */
+    protected ExpressionFactory createDefaultExpressionFactory()
+    {
+        return new MockExpressionFactory();
+    }
+    
+    /**
+     * setup servlets avaliable in the test environment
+     * 
+     * @throws Exception
+     */
+    protected void setUpServlets() throws Exception
+    {
+        setUpFacesServlet();
+    }
+    
+    /**
+     * setup listeners avaliable in the test environment
+     * 
+     * @throws Exception
+     */
+    protected void setUpServletListeners() throws Exception
+    {
+        setUpMyFaces();
+    }
+    
+    /**
+     * 
+     * @return
+     */
+    protected FacesConfigurationProvider createFacesConfigurationProvider()
+    {
+        return new MyFacesMockFacesConfigurationProvider(); 
+    }
+    
+    protected void setUpMyFaces() throws Exception
+    {
+        if (facesConfigurationProvider == null)
+        {
+            facesConfigurationProvider = createFacesConfigurationProvider();
+        }
+        servletContext.setAttribute(
+                DefaultFacesConfigurationProviderFactory.FACES_CONFIGURATION_PROVIDER_INSTANCE_KEY, 
+                facesConfigurationProvider);
+        listener = new StartupServletContextListener();
+        listener.setFacesInitializer(new AbstractFacesInitializer()
+        {
+            
+            @Override
+            protected void initContainerIntegration(ServletContext servletContext,
+                    ExternalContext externalContext)
+            {
+                ExpressionFactory expressionFactory = createDefaultExpressionFactory();
+
+                RuntimeConfig runtimeConfig = buildConfiguration(servletContext, externalContext, expressionFactory);
+            }
+        });
+        listener.contextInitialized(new ServletContextEvent(servletContext));
+    }
+
+    protected void tearDownMyFaces() throws Exception
+    {
+        //Don't tear down FacesConfigurationProvider, because that is shared by all tests.
+        //This helps to reduce the time each test takes 
+        //facesConfigurationProvider = null
+        
+        listener.contextDestroyed(new ServletContextEvent(servletContext));
+    }
+
+    protected void setUpFacesServlet() throws Exception
+    {
+        lifecycleFactory = (LifecycleFactory)FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+        facesContextFactory = (FacesContextFactory)FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
+        lifecycle = lifecycleFactory.getLifecycle(getLifecycleId());
+    }
+    
+    protected void tearDownFacesServlet() throws Exception
+    {
+        lifecycleFactory = null;
+        facesContextFactory = null;
+    }
+    
+    protected void tearDownServlets() throws Exception
+    {
+        tearDownFacesServlet();
+    }
+    
+    protected void tearDownServletListeners() throws Exception
+    {
+        tearDownMyFaces();
+    }
+
+    @After
+    public void tearDown() throws Exception
+    {
+        tearDownServlets();
+
+        tearDownServletListeners();
+        
+        listener = null;
+        
+        servletConfig = null;
+        servletContext = null;
+        
+        FactoryFinder.releaseFactories();
+        
+        Thread.currentThread().setContextClassLoader(threadContextClassLoader);
+        threadContextClassLoader = null;
+    }
+    
+    private String getLifecycleId()
+    {
+        // 1. check for Servlet's init-param
+        // 2. check for global context parameter
+        // 3. use default Lifecycle Id, if none of them was provided
+        String serLifecycleId = servletConfig.getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
+        String appLifecycleId = servletConfig.getServletContext().getInitParameter(FacesServlet.LIFECYCLE_ID_ATTR);
+        appLifecycleId = serLifecycleId == null ? appLifecycleId : serLifecycleId;
+        return appLifecycleId != null ? appLifecycleId : LifecycleFactory.DEFAULT_LIFECYCLE;
+    }
+
+    /**
+     * Call lifecycle.execute(facesContext)
+     * 
+     * @param facesContext
+     */
+    protected void processLifecycleExecute(FacesContext facesContext)
+    {
+        lifecycle.execute(facesContext);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.INVOKE_APPLICATION);
+    }
+
+    /**
+     * Execute restore view phase.
+     * 
+     * @param facesContext
+     * @throws Exception
+     */
+    protected void processRestoreViewPhase(FacesContext facesContext) throws Exception
+    {
+        executePhase(facesContext, PhaseId.RESTORE_VIEW);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RESTORE_VIEW);
+    }
+    
+    /**
+     * Execute apply request values phase. If the responseComplete or renderResponse
+     * flags are set, it returns without do any action.
+     * 
+     * @param facesContext
+     * @throws Exception
+     */
+    protected void processApplyRequestValuesPhase(FacesContext facesContext) throws Exception
+    {
+        if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
+        {
+            return;
+        }
+        executePhase(facesContext, PhaseId.APPLY_REQUEST_VALUES);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.APPLY_REQUEST_VALUES);
+    }
+
+    /**
+     * Execute process validations phase. If the responseComplete or renderResponse
+     * flags are set, it returns without do any action.
+     * 
+     * @param facesContext
+     * @throws Exception
+     */
+    protected void processValidationsPhase(FacesContext facesContext) throws Exception
+    {
+        if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
+        {
+            return;
+        }
+        executePhase(facesContext, PhaseId.PROCESS_VALIDATIONS);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.PROCESS_VALIDATIONS);
+    }
+
+    /**
+     * Execute update model phase. If the responseComplete or renderResponse
+     * flags are set, it returns without do any action.
+     * 
+     * @param facesContext
+     * @throws Exception
+     */
+    protected void processUpdateModelPhase(FacesContext facesContext) throws Exception
+    {
+        if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
+        {
+            return;
+        }
+        executePhase(facesContext, PhaseId.UPDATE_MODEL_VALUES);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.UPDATE_MODEL_VALUES);
+
+    }
+    
+    /**
+     * Execute invoke application phase. If the responseComplete or renderResponse
+     * flags are set, it returns without do any action.
+     * 
+     * @param facesContext
+     * @throws Exception
+     */
+    protected void processInvokeApplicationPhase(FacesContext facesContext) throws Exception
+    {
+        if (facesContext.getRenderResponse() || facesContext.getResponseComplete())
+        {
+            return;
+        }
+        executePhase(facesContext, PhaseId.INVOKE_APPLICATION);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.INVOKE_APPLICATION);
+    }
+
+    /**
+     * Call lifecycle.render(facesContext)
+     * 
+     * @param facesContext
+     */
+    protected void processRender(FacesContext facesContext) throws Exception
+    {
+        processRemainingExecutePhases(facesContext);
+        lifecycle.render(facesContext);
+        facesContext.getAttributes().put(LAST_PHASE_PROCESSED, PhaseId.RENDER_RESPONSE);
+    }
+    
+    protected void processRemainingExecutePhases(FacesContext facesContext) throws Exception
+    {
+        PhaseId lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
+        if (lastPhaseId == null)
+        {
+            processLifecycleExecute(facesContext);
+            return;
+        }
+        else
+        {
+            boolean continueProcess = false;
+            if (PhaseId.RESTORE_VIEW.equals(lastPhaseId))
+            {
+                processApplyRequestValuesPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.APPLY_REQUEST_VALUES.equals(lastPhaseId))
+            {
+                processValidationsPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.PROCESS_VALIDATIONS.equals(lastPhaseId))
+            {
+                processUpdateModelPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.UPDATE_MODEL_VALUES.equals(lastPhaseId))
+            {
+                processInvokeApplicationPhase(facesContext);
+                continueProcess = true;
+            }
+        }
+    }
+
+    protected void processRemainingPhases(FacesContext facesContext) throws Exception
+    {
+        PhaseId lastPhaseId = (PhaseId) facesContext.getAttributes().get(LAST_PHASE_PROCESSED);
+        if (lastPhaseId == null)
+        {
+            processLifecycleExecute(facesContext);
+            processRender(facesContext);
+            return;
+        }
+        else
+        {
+            boolean continueProcess = false;
+            if (PhaseId.RESTORE_VIEW.equals(lastPhaseId))
+            {
+                processApplyRequestValuesPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.APPLY_REQUEST_VALUES.equals(lastPhaseId))
+            {
+                processValidationsPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.PROCESS_VALIDATIONS.equals(lastPhaseId))
+            {
+                processUpdateModelPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.UPDATE_MODEL_VALUES.equals(lastPhaseId))
+            {
+                processInvokeApplicationPhase(facesContext);
+                continueProcess = true;
+            }
+            if (continueProcess || PhaseId.INVOKE_APPLICATION.equals(lastPhaseId))
+            {
+                processRender(facesContext);
+            }
+        }
+    }
+    
+    /**
+     * Indicate if annotation scanning should be done over the classpath. 
+     * By default it is set to false.  
+     * 
+     * @return
+     */
+    protected boolean isScanAnnotations()
+    {
+        return false;
+    }
+    
+    /**
+     * Execute an specified phase, doing some reflection over LifecycleImpl.
+     * 
+     * @param facesContext
+     * @param phase
+     * @throws Exception
+     */
+    protected void executePhase(FacesContext facesContext, PhaseId phase) throws Exception
+    {
+        if (lifecycle instanceof LifecycleImpl)
+        {
+            LifecycleImpl lifecycleImpl = (LifecycleImpl) lifecycle;
+            
+            int phaseId = phase.equals(PhaseId.RESTORE_VIEW) ? 0 :
+                          phase.equals(PhaseId.APPLY_REQUEST_VALUES) ? 1 : 
+                          phase.equals(PhaseId.PROCESS_VALIDATIONS) ? 2 :
+                          phase.equals(PhaseId.UPDATE_MODEL_VALUES) ? 3 : 
+                          phase.equals(PhaseId.INVOKE_APPLICATION) ? 4 : 5 ;
+            
+            Object phaseExecutor = null;
+            if (phaseId < 5)
+            {
+                Field lifecycleExecutorsField = lifecycleImpl.getClass().getDeclaredField("lifecycleExecutors");
+                if (!lifecycleExecutorsField.isAccessible())
+                {
+                    lifecycleExecutorsField.setAccessible(true);
+                }
+                phaseExecutor = ((Object[])lifecycleExecutorsField.get(lifecycleImpl))[phaseId];
+            }
+            else
+            {
+                Field renderExecutorField = lifecycleImpl.getClass().getDeclaredField("renderExecutor");
+                if (!renderExecutorField.isAccessible())
+                {
+                    renderExecutorField.setAccessible(true);
+                }
+                phaseExecutor = renderExecutorField.get(lifecycleImpl);
+            }
+            
+            Object phaseManager = facesContext.getAttributes().get(PHASE_MANAGER_INSTANCE);
+            if (phaseManager == null)
+            {
+                Method getPhaseListenersMethod = lifecycleImpl.getClass().getDeclaredMethod("getPhaseListeners");
+                if (!getPhaseListenersMethod.isAccessible())
+                {
+                    getPhaseListenersMethod.setAccessible(true);
+                }
+                
+                Constructor<?> plmc = PHASE_MANAGER_CLASS.getDeclaredConstructor(new Class[]{Lifecycle.class, FacesContext.class, PhaseListener[].class});
+                if (!plmc.isAccessible())
+                {
+                    plmc.setAccessible(true);
+                }
+                phaseManager = plmc.newInstance(lifecycle, facesContext, getPhaseListenersMethod.invoke(lifecycleImpl, null));
+                facesContext.getAttributes().put(PHASE_MANAGER_INSTANCE, phaseManager);
+            }
+            
+            Method executePhaseMethod = lifecycleImpl.getClass().getDeclaredMethod("executePhase", new Class[]{
+                    FacesContext.class, PHASE_EXECUTOR_CLASS, PHASE_MANAGER_CLASS});
+            if (!executePhaseMethod.isAccessible())
+            {
+                executePhaseMethod.setAccessible(true);
+            }
+            
+            executePhaseMethod.invoke(lifecycleImpl, facesContext, phaseExecutor, phaseManager);
+            
+            if (phase.equals(PhaseId.RENDER_RESPONSE))
+            {
+                facesContext.getAttributes().remove(PHASE_MANAGER_INSTANCE);
+            }
+        }
+        else
+        {
+            throw new UnsupportedOperationException("Cannot execute phase on custom lifecycle instances");
+        }
+    }
+
+    // ------------------------------------------------------ Instance Variables
+
+
+    // Thread context class loader saved and restored after each test
+    private ClassLoader threadContextClassLoader = null;
+
+    // Servlet objects 
+    protected MockServletConfig servletConfig = null;
+    protected MockServletContext servletContext = null;
+
+    // MyFaces specific objects created by the servlet environment
+    protected StartupServletContextListener listener = null;
+    protected FacesConfigurationProvider facesConfigurationProvider = null;
+    
+    protected FacesContextFactory facesContextFactory = null;
+    protected LifecycleFactory lifecycleFactory = null;
+    protected Lifecycle lifecycle;
+
+    private static FacesConfig standardFacesConfig;
+
+    // ------------------------------------------------------ Subclasses
+
+    /**
+     * Mock FacesConfigurationProvider that replace the original ViewDeclarationLanguageFactory with a customized one that
+     * contains only facelets vdl and cache some FacesConfig that does not change to reduce the time required to process each test.
+     * 
+     * @author Leonardo Uribe
+     *
+     */
+    protected class MyFacesMockFacesConfigurationProvider extends DefaultFacesConfigurationProvider
+    {
+        
+        @Override
+        public FacesConfig getStandardFacesConfig(ExternalContext ectx)
+        {
+            if (standardFacesConfig == null)
+            {
+                FacesConfig sfc = super.getStandardFacesConfig(ectx);
+                Factory factory = (Factory) sfc.getFactories().get(0);
+                // Override the default vdl factory with a mock one that only load
+                // facelet views
+                factory.getViewDeclarationLanguageFactory().set(0, MockMyFacesViewDeclarationLanguageFactory.class.getName());
+                standardFacesConfig = sfc;
+            }
+            return standardFacesConfig;
+        }
+
+        @Override
+        public FacesConfig getAnnotationsFacesConfig(ExternalContext ectx,
+                boolean metadataComplete)
+        {
+            if (isScanAnnotations())
+            {
+                return super.getAnnotationsFacesConfig(ectx, metadataComplete);
+            }
+            return null;
+        }
+    }
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,163 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.faces.component.UICommand;
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.component.UIInput;
+import javax.faces.component.html.HtmlCommandButton;
+import javax.faces.component.visit.VisitCallback;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitResult;
+import javax.faces.context.FacesContext;
+import javax.faces.render.ResponseStateManager;
+import javax.servlet.http.Cookie;
+
+import org.apache.myfaces.shared.renderkit.RendererUtils;
+import org.apache.myfaces.test.mock.MockHttpServletRequest;
+import org.apache.myfaces.test.mock.MockHttpServletResponse;
+
+/**
+ * Client that keep track and "translate" the commands done in a JSF component.
+ * It simulates the effect of a browser, but without execute any javascript
+ * or check the html output. If that level of detail is required, use an
+ * in-container alternative like Arquillian and others. This strategy is designed
+ * for server-side testing. 
+ * 
+ * @author Leonardo Uribe
+ *
+ */
+public class MockMyFacesClient
+{
+    private Map<String, String> parameters = new HashMap<String, String>();
+    private Map<String, Cookie> cookies = new HashMap<String, Cookie>();
+    private Map<String, Object> headers = new HashMap<String, Object>();
+    
+    private final FacesContext facesContext;
+    
+    public MockMyFacesClient(FacesContext facesContext)
+    {
+        this.facesContext = facesContext;
+    }
+    
+    public void inputText(UIInput input, String text)
+    {
+        parameters.put(input.getClientId(), text);
+    }
+    
+    public void submit(UICommand command)
+    {
+        if (command instanceof HtmlCommandButton)
+        {
+            UIForm form = getParentForm(command);
+            VisitContext visitContext = VisitContext.createVisitContext(facesContext);
+            form.visitTree(visitContext, new VisitCallback(){
+
+                public VisitResult visit(VisitContext context,
+                        UIComponent target)
+                {
+                    if (target instanceof UIInput)
+                    {
+                        if (!parameters.containsKey(target.getClientId(facesContext)))
+                        {
+                            parameters.put(target.getClientId(facesContext), RendererUtils.getStringValue(facesContext, target));
+                        }
+                    }
+                    return VisitResult.ACCEPT;
+                }
+                
+            });
+            parameters.put(form.getClientId(facesContext)+"_SUBMIT", "1");
+            parameters.put(ResponseStateManager.VIEW_STATE_PARAM, facesContext.getApplication().getStateManager().getViewState(facesContext));
+            Object value = command.getValue();
+            parameters.put(command.getClientId(), value == null ? "" : value.toString());
+            MockHttpServletResponse response = (MockHttpServletResponse) facesContext.getExternalContext().getResponse(); 
+            Cookie cookie = response.getCookie("oam.Flash.RENDERMAP.TOKEN");
+            getCookies().put("oam.Flash.RENDERMAP.TOKEN", cookie);
+        }
+    }
+    
+    public Map<String, String> getParameters()
+    {
+        return parameters;
+    }
+    
+    public Map<String, Object> getHeaders()
+    {
+        return headers;
+    }
+    
+    public Map<String, Cookie> getCookies()
+    {
+        return cookies;
+    }
+    
+    private UIForm getParentForm(UIComponent component)
+    {
+        UIComponent parent = component.getParent();
+        while ( parent != null)
+        {
+            if (parent instanceof UIForm)
+            {
+                return (UIForm) parent;
+            }
+            parent = parent.getParent().getParent();
+        }
+        return null;
+    }
+    
+    /**
+     * Apply all params, headers and cookies into the request.
+     * 
+     * @param request
+     */
+    public void apply(MockHttpServletRequest request)
+    {
+        Map<String, String> inputFields = getParameters();
+        for (Map.Entry<String, String> entry : inputFields.entrySet())
+        {
+            request.addParameter(entry.getKey(), entry.getValue());
+        }
+        Map<String, Object> headerFields = getHeaders();
+        for (Map.Entry<String, Object> entry : headerFields.entrySet())
+        {
+            if (entry.getValue() instanceof String)
+            {
+                request.addHeader(entry.getKey(), (String) entry.getValue());
+            }
+            else if (entry.getValue() instanceof Integer)
+            {
+                request.addIntHeader(entry.getKey(), (Integer) entry.getValue());
+            }
+            else if (entry.getValue() instanceof java.util.Date)
+            {
+                request.addDateHeader(entry.getKey(), ((java.util.Date) entry.getValue()).getTime());
+            }
+        }
+        Map<String, Cookie> cookies = getCookies();
+        for (Map.Entry<String, Cookie> entry : cookies.entrySet())
+        {
+            request.addCookie(entry.getValue());
+        }
+    }
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesClient.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguage.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguage.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguage.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguage.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ELException;
+import javax.faces.FacesException;
+import javax.faces.application.Resource;
+import javax.faces.component.UIViewRoot;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.myfaces.view.ViewDeclarationLanguageStrategy;
+import org.apache.myfaces.view.facelets.FaceletFactory;
+import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
+import org.apache.myfaces.view.facelets.compiler.Compiler;
+
+public class MockMyFacesFaceletViewDeclarationLanguage extends FaceletViewDeclarationLanguage
+{
+    private String _renderedViewId;
+    private Map<Resource, Resource> _scriptComponentResources;
+
+    public MockMyFacesFaceletViewDeclarationLanguage(FacesContext context)
+    {
+        super(context);
+    }
+
+    public MockMyFacesFaceletViewDeclarationLanguage(FacesContext context,
+            ViewDeclarationLanguageStrategy strategy)
+    {
+        super(context);
+    }
+    
+    @Override
+    public void buildView(FacesContext context, UIViewRoot view)
+            throws IOException
+    {
+        _renderedViewId = null;
+        super.buildView(context, view);
+    }
+
+    public void buildView(FacesContext context, UIViewRoot view, String xmlFile) throws IOException
+    {
+        _renderedViewId = xmlFile;
+        view.setViewId(xmlFile);
+        super.buildView(context, view);
+    }
+    
+    @Override
+    public String getRenderedViewId(FacesContext context, String actionId)
+    {
+        if (_renderedViewId != null)
+        {
+            return _renderedViewId;//super.getRenderedViewId(context, actionId);
+        }
+        else
+        {
+            return super.getRenderedViewId(context, actionId);
+        }
+    }    
+
+    @Override
+    public String calculateViewId(FacesContext context, String viewId)
+    {
+        String calculatedViewId = super.calculateViewId(context, viewId);
+        if (calculatedViewId == null)
+        {
+            //can't calculate it, just passthrough the received one
+            calculatedViewId = viewId;
+        }
+        return calculatedViewId;
+    }
+
+    @Override
+    public Compiler createCompiler(FacesContext context)
+    {
+        return super.createCompiler(context);
+    }
+
+    @Override
+    public FaceletFactory createFaceletFactory(FacesContext context,
+            Compiler compiler)
+    {
+        return super.createFaceletFactory(context, compiler);
+    }
+
+    @Override
+    public ResponseWriter createResponseWriter(FacesContext context)
+            throws IOException, FacesException
+    {
+        return super.createResponseWriter(context);
+    }
+
+    @Override
+    public String getDefaultSuffix(FacesContext context)
+            throws FacesException
+    {
+        return super.getDefaultSuffix(context);
+    }
+
+    @Override
+    public String getResponseContentType(FacesContext context, String orig)
+    {
+        return super.getResponseContentType(context, orig);
+    }
+
+    @Override
+    public String getResponseEncoding(FacesContext context, String orig)
+    {
+        return super.getResponseEncoding(context, orig);
+    }
+
+    @Override
+    public void handleFaceletNotFound(FacesContext context, String viewId)
+            throws FacesException, IOException
+    {
+        super.handleFaceletNotFound(context, viewId);
+    }
+
+    @Override
+    public void handleRenderException(FacesContext context, Exception e)
+            throws IOException, ELException, FacesException
+    {
+        super.handleRenderException(context, e);
+    }
+
+    @Override
+    public void initialize(FacesContext context)
+    {
+        super.initialize(context);
+    }
+
+    @Override
+    public void loadDecorators(FacesContext context, Compiler compiler)
+    {
+        super.loadDecorators(context, compiler);
+    }
+
+    @Override
+    public void loadLibraries(FacesContext context, Compiler compiler)
+    {
+        super.loadLibraries(context, compiler);
+    }
+
+    @Override
+    public void loadOptions(FacesContext context, Compiler compiler)
+    {
+        super.loadOptions(context, compiler);
+    }
+
+    @Override
+    public void sendSourceNotFound(FacesContext context, String message)
+    {
+        super.sendSourceNotFound(context, message);
+    }
+
+    @Override
+    public Resource getScriptComponentResource(FacesContext context,
+            Resource componentResource)
+    {
+        if (_scriptComponentResources != null)
+        {
+            Resource installedResource = _scriptComponentResources.get(componentResource);
+            if (installedResource != null)
+            {
+                // if we have a Resource installed for this componentResource, return it
+                return installedResource;
+            }
+        }
+        return super.getScriptComponentResource(context, componentResource);
+    }
+    
+    /**
+     * This method sets the scriptResource for a given componentResource so that
+     * a call to getScriptComponentResource() with the given componentResource
+     * will return the installed scriptResource.
+     * @param componentResource
+     * @param scriptResource
+     */
+    public void setScriptComponentResource(Resource componentResource, Resource scriptResource)
+    {
+        if (_scriptComponentResources == null)
+        {
+            _scriptComponentResources = new HashMap<Resource, Resource>();
+        }
+        _scriptComponentResources.put(componentResource, scriptResource);
+    }
+
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguageStrategy.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguageStrategy.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguageStrategy.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguageStrategy.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import java.util.regex.Pattern;
+
+import javax.faces.application.ViewHandler;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewDeclarationLanguage;
+
+import org.apache.myfaces.view.ViewDeclarationLanguageStrategy;
+
+/**
+ * @author Leonardo Uribe 
+ * @since 2.0
+ */
+public class MockMyFacesFaceletViewDeclarationLanguageStrategy implements ViewDeclarationLanguageStrategy
+{
+    private Pattern _acceptPatterns;
+    private String _extension;
+
+    private ViewDeclarationLanguage _language;
+
+    public MockMyFacesFaceletViewDeclarationLanguageStrategy()
+    {
+        FacesContext context = FacesContext.getCurrentInstance();
+        ExternalContext eContext = context.getExternalContext();
+
+        _acceptPatterns = loadAcceptPattern(eContext);
+
+        _extension = loadFaceletExtension(eContext);
+
+        _language = new MockMyFacesFaceletViewDeclarationLanguage(context, this);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public ViewDeclarationLanguage getViewDeclarationLanguage()
+    {
+        return _language;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public boolean handles(String viewId)
+    {
+        if (viewId == null)
+        {
+            return false;
+        }
+        // Check extension first as it's faster than mappings
+        if (viewId.endsWith(_extension))
+        {
+            // If the extension matches, it's a Facelet viewId.
+            return true;
+        }
+
+        // Otherwise, try to match the view identifier with the facelet mappings
+        return _acceptPatterns != null && _acceptPatterns.matcher(viewId).matches();
+    }
+
+    /**
+     * Load and compile a regular expression pattern built from the Facelet view mapping parameters.
+     * 
+     * @param context
+     *            the application's external context
+     * 
+     * @return the compiled regular expression
+     */
+    private Pattern loadAcceptPattern(ExternalContext context)
+    {
+        assert context != null;
+
+        String mappings = context.getInitParameter(ViewHandler.FACELETS_VIEW_MAPPINGS_PARAM_NAME);
+        if(mappings == null)    //consider alias facelets.VIEW_MAPPINGS
+        {
+            mappings = context.getInitParameter("facelets.VIEW_MAPPINGS");
+        }
+        if (mappings == null)
+        {
+            return null;
+        }
+
+        // Make sure the mappings contain something
+        mappings = mappings.trim();
+        if (mappings.length() == 0)
+        {
+            return null;
+        }
+
+        return Pattern.compile(toRegex(mappings));
+    }
+
+    private String loadFaceletExtension(ExternalContext context)
+    {
+        assert context != null;
+
+        String suffix = context.getInitParameter(ViewHandler.FACELETS_SUFFIX_PARAM_NAME);
+        if (suffix == null)
+        {
+            suffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
+        }
+        else
+        {
+            suffix = suffix.trim();
+            if (suffix.length() == 0)
+            {
+                suffix = ViewHandler.DEFAULT_FACELETS_SUFFIX;
+            }
+        }
+
+        return suffix;
+    }
+
+    /**
+     * Convert the specified mapping string to an equivalent regular expression.
+     * 
+     * @param mappings
+     *            le mapping string
+     * 
+     * @return an uncompiled regular expression representing the mappings
+     */
+    private String toRegex(String mappings)
+    {
+        assert mappings != null;
+
+        // Get rid of spaces
+        mappings = mappings.replaceAll("\\s", "");
+
+        // Escape '.'
+        mappings = mappings.replaceAll("\\.", "\\\\.");
+
+        // Change '*' to '.*' to represent any match
+        mappings = mappings.replaceAll("\\*", ".*");
+
+        // Split the mappings by changing ';' to '|'
+        mappings = mappings.replaceAll(";", "|");
+
+        return mappings;
+    }
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesFaceletViewDeclarationLanguageStrategy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesViewDeclarationLanguageFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesViewDeclarationLanguageFactory.java?rev=1189484&view=auto
==============================================================================
--- myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesViewDeclarationLanguageFactory.java (added)
+++ myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesViewDeclarationLanguageFactory.java Wed Oct 26 21:34:01 2011
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.myfaces.mc.test.core;
+
+import javax.faces.FacesException;
+import javax.faces.view.ViewDeclarationLanguage;
+import javax.faces.view.ViewDeclarationLanguageFactory;
+
+import org.apache.myfaces.view.ViewDeclarationLanguageStrategy;
+import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguageStrategy;
+
+public class MockMyFacesViewDeclarationLanguageFactory extends ViewDeclarationLanguageFactory
+{
+
+    private boolean _initialized;
+    private ViewDeclarationLanguageStrategy[] _supportedLanguages;
+    
+    public MockMyFacesViewDeclarationLanguageFactory()
+    {
+        _initialized = false;
+    }
+
+    @Override
+    public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId)
+    {
+        initialize();
+        
+        for (ViewDeclarationLanguageStrategy strategy : _supportedLanguages)
+        {
+            if (strategy.handles(viewId))
+            {
+                return strategy.getViewDeclarationLanguage();
+            }
+        }
+        
+        throw new FacesException("Cannot find a valid PDL for view id " + viewId);
+    }
+
+    private synchronized void initialize()
+    {
+        if (!_initialized)
+        {
+            _supportedLanguages = new ViewDeclarationLanguageStrategy[1];
+            _supportedLanguages[0] = new MockMyFacesFaceletViewDeclarationLanguageStrategy();
+        }
+    }
+
+}

Propchange: myfaces/core/branches/2.0.x/impl/src/test/java/org/apache/myfaces/mc/test/core/MockMyFacesViewDeclarationLanguageFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native