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 2014/03/03 02:03:46 UTC

svn commit: r1573413 [1/2] - in /myfaces/core/trunk: impl-test/src/main/java/org/apache/myfaces/mc/test/core/ impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/ impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/ impl-test/sr...

Author: lu4242
Date: Mon Mar  3 01:03:45 2014
New Revision: 1573413

URL: http://svn.apache.org/r1573413
Log:
MYFACES-3862 Set mock InitialContextFactory for junit testing with myfaces impl test, add @BeforeJSFInit annotation and fix some issues found 

Added:
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java   (with props)
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java   (with props)
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContext.java   (with props)
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java   (with props)
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java   (with props)
    myfaces/core/trunk/impl-test/src/main/resources/   (with props)
    myfaces/core/trunk/impl-test/src/test/   (with props)
    myfaces/core/trunk/impl-test/src/test/java/   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java   (with props)
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java   (with props)
Modified:
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java
    myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfTestContainer.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfTestContainer.java

Modified: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java (original)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java Mon Mar  3 01:03:45 2014
@@ -21,12 +21,12 @@ package org.apache.myfaces.mc.test.core;
 import javax.faces.FacesException;
 import javax.faces.context.ExternalContext;
 import javax.servlet.ServletContext;
+import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.spi.InjectionProvider;
 import org.apache.myfaces.spi.InjectionProviderException;
 import org.apache.myfaces.spi.InjectionProviderFactory;
 import org.apache.myfaces.spi.impl.CDIAnnotationDelegateInjectionProvider;
 import org.apache.myfaces.webapp.AbstractFacesInitializer;
-import org.apache.webbeans.servlet.WebBeansConfigurationListener;
 
 /**
  *
@@ -34,7 +34,8 @@ import org.apache.webbeans.servlet.WebBe
 public class AbstractMyFacesCDIRequestTestCase extends AbstractMyFacesRequestTestCase
 {
     
-    protected WebBeansConfigurationListener owbListener;
+    //protected WebBeansConfigurationListener owbListener;
+    private Object owbListener;
     protected InjectionProvider injectionProvider;
     
     @Override
@@ -48,8 +49,16 @@ public class AbstractMyFacesCDIRequestTe
     @Override
     protected void setUpServletListeners() throws Exception
     {
-        owbListener = new WebBeansConfigurationListener();
-        webContainer.subscribeListener(owbListener);
+        Class listenerClass = ClassUtils.classForName("org.apache.webbeans.servlet.WebBeansConfigurationListener");
+        if (listenerClass == null)
+        {
+            listenerClass = ClassUtils.classForName("org.jboss.weld.environment.servlet.Listener");
+        }
+        if (listenerClass != null)
+        {
+            owbListener = ClassUtils.newInstance(listenerClass);
+            webContainer.subscribeListener(owbListener);
+        }
         super.setUpServletListeners();
     }
 

Modified: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java (original)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java Mon Mar  3 01:03:45 2014
@@ -56,6 +56,7 @@ import javax.faces.lifecycle.Lifecycle;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.view.ViewDeclarationLanguage;
 import javax.faces.webapp.FacesServlet;
+import javax.naming.Context;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.http.HttpServletResponse;
@@ -71,7 +72,11 @@ import org.apache.myfaces.lifecycle.View
 import org.apache.myfaces.mc.test.core.annotation.DeclareFacesConfig;
 import org.apache.myfaces.mc.test.core.annotation.ManagedBeans;
 import org.apache.myfaces.mc.test.core.annotation.PageBean;
+import org.apache.myfaces.mc.test.core.annotation.TestConfig;
+import org.apache.myfaces.mc.test.core.mock.DefaultContext;
+import org.apache.myfaces.mc.test.core.mock.MockInitialContextFactory;
 import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.spi.FacesConfigurationProvider;
 import org.apache.myfaces.spi.impl.DefaultFacesConfigurationProviderFactory;
 import org.apache.myfaces.spi.impl.NoInjectionAnnotationInjectionProvider;
@@ -155,11 +160,20 @@ public abstract class AbstractMyFacesTes
                         new URLClassLoader(new URL[0], this.getClass()
                                 .getClassLoader()));
         
-        jsfConfiguration = sharedConfiguration.get(this.getClass().getName());
+        jsfConfiguration = sharedConfiguration.get(getTestJavaClass().getName());
         if (jsfConfiguration == null)
         {
             jsfConfiguration = new SharedFacesConfiguration();
         }
+        
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        boolean enableJNDI = (testConfig != null) ? testConfig.enableJNDI() : true;
+        if (enableJNDI)
+        {
+            System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName());
+            jndiContext = new DefaultContext();
+            MockInitialContextFactory.setCurrentContext(jndiContext);
+        }
 
         // Set up Servlet API Objects
         setUpServletObjects();
@@ -173,7 +187,7 @@ public abstract class AbstractMyFacesTes
         
         setUpFacesServlet();
         
-        sharedConfiguration.put(this.getClass().getName(), jsfConfiguration);
+        sharedConfiguration.put(getTestJavaClass().getName(), jsfConfiguration);
     }
     
     /**
@@ -258,6 +272,12 @@ public abstract class AbstractMyFacesTes
      */
     protected String getWebappResourcePath()
     {
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        if (testConfig != null && testConfig.webappResourcePath() != null &&
+            !"testClassResourcePackage".equals(testConfig.webappResourcePath()))
+        {
+            return testConfig.webappResourcePath();
+        }
         return this.getClass().getName().substring(0,
                 this.getClass().getName().lastIndexOf('.')).replace('.', '/')
                 + "/";
@@ -271,6 +291,13 @@ public abstract class AbstractMyFacesTes
      */
     protected ExpressionFactory createExpressionFactory()
     {
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        if (testConfig != null && testConfig.expressionFactory() != null &&
+            testConfig.expressionFactory().length() > 0)
+        {
+            return (ExpressionFactory) ClassUtils.newInstance(
+                testConfig.expressionFactory(), ExpressionFactory.class);
+        }
         return new MockExpressionFactory();
     }
     
@@ -371,6 +398,11 @@ public abstract class AbstractMyFacesTes
         
         FactoryFinder.releaseFactories();
         
+        if (jndiContext != null)
+        {
+            MockInitialContextFactory.clearCurrentContext();
+        }
+        
         Thread.currentThread().setContextClassLoader(threadContextClassLoader);
         threadContextClassLoader = null;
     }
@@ -681,6 +713,11 @@ public abstract class AbstractMyFacesTes
      */
     protected boolean isScanAnnotations()
     {
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        if (testConfig != null)
+        {
+            return testConfig.scanAnnotations();
+        }
         return false;
     }
     
@@ -1167,6 +1204,7 @@ public abstract class AbstractMyFacesTes
 
     // Thread context class loader saved and restored after each test
     private ClassLoader threadContextClassLoader = null;
+    private Context jndiContext = null;
 
     // Servlet objects 
     protected MockServletConfig servletConfig = null;
@@ -1185,6 +1223,12 @@ public abstract class AbstractMyFacesTes
     private static Map<String, SharedFacesConfiguration> sharedConfiguration =
         new ConcurrentHashMap<String, SharedFacesConfiguration>();
     private SharedFacesConfiguration jsfConfiguration;
+    
+    protected Class<?> getTestJavaClass()
+    {
+        return this.getClass();
+    }
+    
 
     // ------------------------------------------------------ Subclasses
 
@@ -1233,7 +1277,7 @@ public abstract class AbstractMyFacesTes
                     facesConfig = super.getAnnotationsFacesConfig(ectx, metadataComplete); 
                 }
 
-                ManagedBeans annoManagedBeans = testCase.getClass().getAnnotation(ManagedBeans.class);
+                ManagedBeans annoManagedBeans = getTestJavaClass().getAnnotation(ManagedBeans.class);
                 if (annoManagedBeans != null)
                 {
                     if (facesConfig == null)
@@ -1255,7 +1299,7 @@ public abstract class AbstractMyFacesTes
                     }
                 }
 
-                PageBean annoPageBean = testCase.getClass().getAnnotation(PageBean.class);
+                PageBean annoPageBean = getTestJavaClass().getAnnotation(PageBean.class);
                 if (annoPageBean != null)
                 {
                     if (facesConfig == null)
@@ -1329,10 +1373,10 @@ public abstract class AbstractMyFacesTes
         {
             List<FacesConfig> appConfigResources = super.getContextSpecifiedFacesConfig(ectx);
             
-            DeclareFacesConfig annoFacesConfig = testCase.getClass().getAnnotation(DeclareFacesConfig.class);
+            DeclareFacesConfig annoFacesConfig = getTestJavaClass().getAnnotation(DeclareFacesConfig.class);
             if (annoFacesConfig != null)
             {
-                Logger log = Logger.getLogger(testCase.getClass().getName());
+                Logger log = Logger.getLogger(getTestJavaClass().getName());
                 try
                 {
                     for (String systemId : annoFacesConfig.value())

Added: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java (added)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,37 @@
+/*
+ * 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.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value =
+{
+    ElementType.METHOD
+})
+public @interface BeforeJSFInit
+{
+    
+}

Propchange: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java (original)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java Mon Mar  3 01:03:45 2014
@@ -47,4 +47,6 @@ public @interface TestConfig
     
     String servletPath() default "/faces";
     
+    boolean enableJNDI() default true;
+    
 }

Added: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java (added)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,553 @@
+/*
+ * 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.mock;
+
+import javax.naming.Binding;
+import javax.naming.CompositeName;
+import javax.naming.Context;
+import javax.naming.LinkRef;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NotContextException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.Reference;
+import javax.naming.spi.NamingManager;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * A simple spring based JNDI context which is mutable
+ *
+ * NOTE: Code copied from org.apache.xbean.spring.jndi.DefaultContext
+ *
+ * @version $Revision: 657 $
+ */
+public class DefaultContext implements Context, Serializable
+{
+
+    private static final long serialVersionUID = -5754338187296859149L;
+    protected static final NameParser NAMED_PARSER = new NameParserImpl();
+
+    private boolean freeze = false;
+
+    protected final Hashtable environment;        // environment for this context
+    protected final Map bindings;         // bindings at my level
+    protected final Map treeBindings;     // all bindings under me
+
+    private boolean frozen = false;
+    private String nameInNamespace = "";
+    public static final String SEPARATOR = "/";
+
+    public DefaultContext()
+    {
+        environment = new Hashtable();
+        bindings = new HashMap();
+        treeBindings = new HashMap();
+    }
+
+    public DefaultContext(Hashtable env)
+    {
+        if (env == null)
+        {
+            this.environment = new Hashtable();
+        }
+        else
+        {
+            this.environment = new Hashtable(env);
+        }
+        this.bindings = new HashMap();
+        this.treeBindings = new HashMap();
+    }
+
+    public DefaultContext(Hashtable environment, Map bindings)
+    {
+        if (environment == null)
+        {
+            this.environment = new Hashtable();
+        }
+        else
+        {
+            this.environment = new Hashtable(environment);
+        }
+        this.bindings = bindings;
+        treeBindings = new HashMap();
+        frozen = true;
+    }
+
+    public DefaultContext(Hashtable environment, Map bindings, String nameInNamespace)
+    {
+        this(environment, bindings);
+        this.nameInNamespace = nameInNamespace;
+    }
+
+    protected DefaultContext(DefaultContext clone, Hashtable env)
+    {
+        this.bindings = clone.bindings;
+        this.treeBindings = clone.treeBindings;
+        this.environment = new Hashtable(env);
+    }
+
+    protected DefaultContext(DefaultContext clone, Hashtable env, String nameInNamespace)
+    {
+        this(clone, env);
+        this.nameInNamespace = nameInNamespace;
+    }
+
+    public Object addToEnvironment(String propName, Object propVal) throws NamingException
+    {
+        return environment.put(propName, propVal);
+    }
+
+    public Hashtable getEnvironment() throws NamingException
+    {
+        return (Hashtable) environment.clone();
+    }
+
+    public Object removeFromEnvironment(String propName) throws NamingException
+    {
+        return environment.remove(propName);
+    }
+
+    public Object lookup(String name) throws NamingException
+    {
+        if (name.length() == 0)
+        {
+            return this;
+        }
+        Object result = treeBindings.get(name);
+        if (result == null)
+        {
+            result = bindings.get(name);
+        }
+        if (result == null)
+        {
+            int pos = name.indexOf(':');
+            if (pos > 0)
+            {
+                String scheme = name.substring(0, pos);
+                Context ctx = NamingManager.getURLContext(scheme, environment);
+                if (ctx == null)
+                {
+                    throw new NamingException("scheme " + scheme + " not recognized");
+                }
+                return ctx.lookup(name);
+            }
+            else
+            {
+                // Split out the first name of the path
+                // and look for it in the bindings map.
+                CompositeName path = new CompositeName(name);
+
+                if (path.size() == 0)
+                {
+                    return this;
+                }
+                else
+                {
+                    String first = path.get(0);
+                    Object obj = bindings.get(first);
+                    if (obj == null)
+                    {
+                        throw new NameNotFoundException(name);
+                    }
+                    else if (obj instanceof Context && path.size() > 1)
+                    {
+                        Context subContext = (Context) obj;
+                        obj = subContext.lookup(path.getSuffix(1));
+                    }
+                    return obj;
+                }
+            }
+        }
+        if (result instanceof LinkRef)
+        {
+            LinkRef ref = (LinkRef) result;
+            result = lookup(ref.getLinkName());
+        }
+        if (result instanceof Reference)
+        {
+            try
+            {
+                result = NamingManager.getObjectInstance(result, null, null, this.environment);
+            }
+            catch (NamingException e)
+            {
+                throw e;
+            }
+            catch (Exception e)
+            {
+                throw (NamingException) new NamingException("could not look up : " + name).initCause(e);
+            }
+        }
+        if (result instanceof DefaultContext)
+        {
+            String prefix = getNameInNamespace();
+            if (prefix.length() > 0)
+            {
+                prefix = prefix + SEPARATOR;
+            }
+            result = new DefaultContext((DefaultContext) result, environment, prefix + name);
+        }
+        return result;
+    }
+
+    public Object lookup(Name name) throws NamingException
+    {
+        return lookup(name.toString());
+    }
+
+    public Object lookupLink(String name) throws NamingException
+    {
+        return lookup(name);
+    }
+
+    public Name composeName(Name name, Name prefix) throws NamingException
+    {
+        Name result = (Name) prefix.clone();
+        result.addAll(name);
+        return result;
+    }
+
+    public String composeName(String name, String prefix) throws NamingException
+    {
+        CompositeName result = new CompositeName(prefix);
+        result.addAll(new CompositeName(name));
+        return result.toString();
+    }
+
+    public NamingEnumeration list(String name) throws NamingException
+    {
+        Object o = lookup(name);
+        if (o == this)
+        {
+            return new DefaultContext.ListEnumeration();
+        }
+        else if (o instanceof Context)
+        {
+            return ((Context) o).list("");
+        }
+        else
+        {
+            throw new NotContextException();
+        }
+    }
+
+    public NamingEnumeration listBindings(String name) throws NamingException
+    {
+        Object o = lookup(name);
+        if (o == this)
+        {
+            return new DefaultContext.ListBindingEnumeration();
+        }
+        else if (o instanceof Context)
+        {
+            return ((Context) o).listBindings("");
+        }
+        else
+        {
+            throw new NotContextException();
+        }
+    }
+
+    public Object lookupLink(Name name) throws NamingException
+    {
+        return lookupLink(name.toString());
+    }
+
+    public NamingEnumeration list(Name name) throws NamingException
+    {
+        return list(name.toString());
+    }
+
+    public NamingEnumeration listBindings(Name name) throws NamingException
+    {
+        return listBindings(name.toString());
+    }
+
+    public void bind(Name name, Object value) throws NamingException
+    {
+        bind(name.toString(), value);
+    }
+
+    public void bind(String name, Object value) throws NamingException
+    {
+        checkFrozen();
+        internalBind(name, value);
+    }
+
+    public void close() throws NamingException
+    {
+        // ignore
+    }
+
+    public Context createSubcontext(Name name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public Context createSubcontext(String name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public void destroySubcontext(Name name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public void destroySubcontext(String name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public String getNameInNamespace() throws NamingException
+    {
+        return nameInNamespace;
+    }
+
+    public NameParser getNameParser(Name name) throws NamingException
+    {
+        return NAMED_PARSER;
+    }
+
+    public NameParser getNameParser(String name) throws NamingException
+    {
+        return NAMED_PARSER;
+    }
+
+    public void rebind(Name name, Object value) throws NamingException
+    {
+        rebind(name.toString(), value);
+    }
+
+    public void rebind(String name, Object value) throws NamingException
+    {
+        checkFrozen();
+        internalBind(name, value, true);
+    }
+
+    public void rename(Name oldName, Name newName) throws NamingException
+    {
+        checkFrozen();
+        Object value = lookup(oldName);
+        unbind(oldName);
+        bind(newName, value);
+    }
+
+    public void rename(String oldName, String newName) throws NamingException
+    {
+        Object value = lookup(oldName);
+        unbind(oldName);
+        bind(newName, value);
+    }
+
+    public void unbind(Name name) throws NamingException
+    {
+        unbind(name.toString());
+    }
+
+    public void unbind(String name) throws NamingException
+    {
+        checkFrozen();
+        internalBind(name, null, true);
+    }
+
+    private abstract class LocalNamingEnumeration implements NamingEnumeration
+    {
+
+        private Iterator i = bindings.entrySet().iterator();
+
+        public boolean hasMore() throws NamingException
+        {
+            return i.hasNext();
+        }
+
+        public boolean hasMoreElements()
+        {
+            return i.hasNext();
+        }
+
+        protected Map.Entry getNext()
+        {
+            return (Map.Entry) i.next();
+        }
+
+        public void close() throws NamingException
+        {
+        }
+    }
+
+    private class ListEnumeration extends DefaultContext.LocalNamingEnumeration
+    {
+
+        public Object next() throws NamingException
+        {
+            return nextElement();
+        }
+
+        public Object nextElement()
+        {
+            Map.Entry entry = getNext();
+            return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName());
+        }
+    }
+
+    private class ListBindingEnumeration extends DefaultContext.LocalNamingEnumeration
+    {
+
+        public Object next() throws NamingException
+        {
+            return nextElement();
+        }
+
+        public Object nextElement()
+        {
+            Map.Entry entry = getNext();
+            return new Binding((String) entry.getKey(), entry.getValue());
+        }
+    }
+
+    public Map getEntries()
+    {
+        return new HashMap(bindings);
+    }
+
+    public void setEntries(Map entries) throws NamingException
+    {
+        if (entries != null)
+        {
+            for (Iterator iter = entries.entrySet().iterator(); iter.hasNext();)
+            {
+                Map.Entry entry = (Map.Entry) iter.next();
+                String name = (String) entry.getKey();
+                Object value = entry.getValue();
+                internalBind(name, value);
+            }
+        }
+    }
+
+    public boolean isFreeze()
+    {
+        return freeze;
+    }
+
+    public void setFreeze(boolean freeze)
+    {
+        this.freeze = freeze;
+    }
+
+    /**
+     * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses. It binds
+     * every possible lookup into a map in each context. To do this, each context strips off one name segment and if
+     * necessary creates a new context for it. Then it asks that context to bind the remaining name. It returns a map
+     * containing all the bindings from the next context, plus the context it just created (if it in fact created it).
+     * (the names are suitably extended by the segment originally lopped off).
+     *
+     * @param name
+     * @param value
+     * @return
+     * @throws javax.naming.NamingException
+     */
+    protected Map internalBind(String name, Object value) throws NamingException
+    {
+        return internalBind(name, value, false);
+
+    }
+
+    protected Map internalBind(String name, Object value, boolean allowRebind) throws NamingException
+    {
+
+        if (name == null || name.length() == 0)
+        {
+            throw new NamingException("Invalid Name " + name);
+        }
+        if (frozen)
+        {
+            throw new NamingException("Read only");
+        }
+
+        Map newBindings = new HashMap();
+        int pos = name.indexOf('/');
+        if (pos == -1)
+        {
+            Object oldValue = treeBindings.put(name, value);
+            if (!allowRebind && oldValue != null)
+            {
+                throw new NamingException("Something already bound at " + name);
+            }
+            bindings.put(name, value);
+            newBindings.put(name, value);
+        }
+        else
+        {
+            String segment = name.substring(0, pos);
+
+            if (segment == null || segment.length() == 0)
+            {
+                throw new NamingException("Invalid segment " + segment);
+            }
+            Object o = treeBindings.get(segment);
+            if (o == null)
+            {
+                o = newContext();
+                treeBindings.put(segment, o);
+                bindings.put(segment, o);
+                newBindings.put(segment, o);
+            }
+            else if (!(o instanceof DefaultContext))
+            {
+                throw new NamingException("Something already bound where a subcontext should go");
+            }
+            DefaultContext defaultContext = (DefaultContext) o;
+            String remainder = name.substring(pos + 1);
+            Map subBindings = defaultContext.internalBind(remainder, value, allowRebind);
+            for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();)
+            {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                String subName = segment + "/" + (String) entry.getKey();
+                Object bound = entry.getValue();
+                treeBindings.put(subName, bound);
+                newBindings.put(subName, bound);
+            }
+        }
+        return newBindings;
+    }
+
+    protected void checkFrozen() throws OperationNotSupportedException
+    {
+        if (isFreeze())
+        {
+            throw new OperationNotSupportedException("JNDI context is frozen!");
+        }
+    }
+
+    protected DefaultContext newContext()
+    {
+        return new DefaultContext();
+    }
+
+}

Propchange: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContext.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContext.java (added)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContext.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,50 @@
+/*
+ * 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.mock;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+/**
+ *
+ */
+public class MockInitialContext extends InitialContext
+{
+
+    private Map<String, Object> bindings = new HashMap<String, Object>();
+
+    public MockInitialContext() throws NamingException
+    {
+    }
+
+    @Override
+    public void bind(String name, Object obj)
+        throws NamingException
+    {
+        bindings.put(name, obj);
+    }
+
+    @Override
+    public Object lookup(String name) throws NamingException
+    {
+        return bindings.get(name);
+    }
+}

Propchange: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java (added)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,63 @@
+/*
+ * 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.mock;
+
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+/**
+ * Mock per-thread implementation of InitialContextFactory
+ *
+ */
+public class MockInitialContextFactory implements InitialContextFactory
+{
+
+    private static ThreadLocal<Context> currentInstance = new ThreadLocal<Context>();
+
+    public Context getInitialContext(Hashtable<?, ?> environment)
+        throws NamingException
+    {
+        return currentInstance.get();
+    }
+    
+    public static void setCurrentContext(Context context)
+    {
+        currentInstance.set(context);
+    }
+
+    public static void clearCurrentContext()
+    {
+        currentInstance.remove();
+    }    
+
+    public static void bind(String name, Object obj)
+    {
+        try
+        {
+            currentInstance.get().bind(name, obj);
+        }
+        catch (NamingException e)
+        { // can't happen.
+            throw new RuntimeException(e);
+        }
+    }
+    
+}

Propchange: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java (added)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,40 @@
+/*
+ * 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.mock;
+
+import javax.naming.CompositeName;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+/**
+ * A default implementation of {@link NameParser}
+ *
+ * NOTE: Code copied from org.apache.xbean.spring.jndi.NameParserImpl
+ *
+ * @version $Revision: 1.2 $
+ */
+public class NameParserImpl implements NameParser
+{
+
+    public Name parse(String name) throws NamingException
+    {
+        return new CompositeName(name);
+    }
+}

Propchange: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java (original)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java Mon Mar  3 01:03:45 2014
@@ -232,7 +232,7 @@ public class AbstractJsfRequestTestConta
     
     protected String getContextPath()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null)
         {
             return testConfig.contextPath();
@@ -242,7 +242,7 @@ public class AbstractJsfRequestTestConta
     
     protected String getServletPath()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null)
         {
             return testConfig.servletPath();

Modified: myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfTestContainer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfTestContainer.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfTestContainer.java (original)
+++ myfaces/core/trunk/impl-test/src/main/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfTestContainer.java Mon Mar  3 01:03:45 2014
@@ -54,8 +54,10 @@ import javax.faces.lifecycle.Lifecycle;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.view.ViewDeclarationLanguage;
 import javax.faces.webapp.FacesServlet;
+import javax.naming.Context;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.myfaces.config.ConfigFilesXmlValidationUtils;
 import org.apache.myfaces.config.DefaultFacesConfigurationProvider;
@@ -65,6 +67,7 @@ import org.apache.myfaces.config.element
 import org.apache.myfaces.config.impl.digester.elements.FactoryImpl;
 import org.apache.myfaces.lifecycle.LifecycleImpl;
 import org.apache.myfaces.lifecycle.ViewNotFoundException;
+import org.apache.myfaces.mc.test.core.annotation.BeforeJSFInit;
 import org.apache.myfaces.mc.test.core.mock.MockMyFacesViewDeclarationLanguageFactory;
 import org.apache.myfaces.mc.test.core.annotation.DeclareFacesConfig;
 import org.apache.myfaces.mc.test.core.annotation.ManagedBeans;
@@ -72,6 +75,8 @@ import org.apache.myfaces.mc.test.core.a
 import org.apache.myfaces.mc.test.core.annotation.PageBean;
 import org.apache.myfaces.mc.test.core.annotation.SetupWebConfigParams;
 import org.apache.myfaces.mc.test.core.annotation.TestServletListeners;
+import org.apache.myfaces.mc.test.core.mock.DefaultContext;
+import org.apache.myfaces.mc.test.core.mock.MockInitialContextFactory;
 import org.apache.myfaces.shared.config.MyfacesConfig;
 import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.spi.FacesConfigurationProvider;
@@ -156,11 +161,20 @@ public class AbstractJsfTestContainer
                         new URLClassLoader(new URL[0], this.getClass()
                                 .getClassLoader()));
         
-        jsfConfiguration = sharedConfiguration.get(this.testClass.getName());
+        jsfConfiguration = sharedConfiguration.get(getTestJavaClass().getName());
         if (jsfConfiguration == null)
         {
             jsfConfiguration = new SharedFacesConfiguration();
         }
+        
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        boolean enableJNDI = (testConfig != null) ? testConfig.enableJNDI() : true;
+        if (enableJNDI)
+        {
+            System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName());
+            jndiContext = new DefaultContext();
+            MockInitialContextFactory.setCurrentContext(jndiContext);
+        }
 
         // Set up Servlet API Objects
         setUpServletObjects();
@@ -174,7 +188,7 @@ public class AbstractJsfTestContainer
         
         setUpFacesServlet();
         
-        sharedConfiguration.put(this.testClass.getName(), jsfConfiguration);
+        sharedConfiguration.put(getTestJavaClass().getName(), jsfConfiguration);
     }
     
     /**
@@ -219,14 +233,14 @@ public class AbstractJsfTestContainer
         servletContext.addInitParameter("org.apache.myfaces.config.annotation.LifecycleProvider",
             NoInjectionAnnotationLifecycleProvider.class.getName());
         
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null && testConfig.oamAnnotationScanPackages() != null &&
             testConfig.oamAnnotationScanPackages().length() > 0)
         {
             servletContext.addInitParameter("org.apache.myfaces.annotation.SCAN_PACKAGES",
-                "org.apache.myfaces.application.contracts");
+                testConfig.oamAnnotationScanPackages());
         }
-        
+
         List<FrameworkMethod> setupWebConfigParamMethods = testClass.getAnnotatedMethods(SetupWebConfigParams.class);
         if (setupWebConfigParamMethods != null && !setupWebConfigParamMethods.isEmpty())
         {
@@ -282,7 +296,7 @@ public class AbstractJsfTestContainer
      */
     protected String getWebappResourcePath()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null && testConfig.webappResourcePath() != null &&
             !"testClassResourcePackage".equals(testConfig.webappResourcePath()))
         {
@@ -301,7 +315,7 @@ public class AbstractJsfTestContainer
      */
     protected ExpressionFactory createExpressionFactory()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null && testConfig.expressionFactory() != null &&
             testConfig.expressionFactory().length() > 0)
         {
@@ -328,7 +342,7 @@ public class AbstractJsfTestContainer
      */
     protected void setUpServletListeners()
     {
-        TestServletListeners testServletListeners = testClass.getJavaClass().getAnnotation(TestServletListeners.class);
+        TestServletListeners testServletListeners = getTestJavaClass().getAnnotation(TestServletListeners.class);
         if (testServletListeners != null && testServletListeners.value() != null)
         {
             for (String listener : testServletListeners.value())
@@ -344,6 +358,36 @@ public class AbstractJsfTestContainer
             }
         }
 
+        // Subscribe a listener so we can trigger a method after all listeners but before initialize MyFaces
+        webContainer.subscribeListener(new ServletContextListener()
+        {
+            @Override
+            public void contextInitialized(ServletContextEvent sce)
+            {
+                List<FrameworkMethod> setupWebConfigParamMethods = testClass.getAnnotatedMethods(BeforeJSFInit.class);
+                if (setupWebConfigParamMethods != null && !setupWebConfigParamMethods.isEmpty())
+                {
+                    for (FrameworkMethod fm : setupWebConfigParamMethods)
+                    {
+                        try
+                        {
+                            fm.invokeExplosively(testInstance);
+                        }
+                        catch (Throwable ex)
+                        {
+                            throw new FacesException(ex);
+                        }
+                    }
+                }
+            }
+
+            @Override
+            public void contextDestroyed(ServletContextEvent sce)
+            {
+            }
+            
+        });
+
         //owbListener = new WebBeansConfigurationListener();
         //webContainer.subscribeListener(owbListener);
         setUpMyFaces();
@@ -426,6 +470,11 @@ public class AbstractJsfTestContainer
         
         FactoryFinder.releaseFactories();
         
+        if (jndiContext != null)
+        {
+            MockInitialContextFactory.clearCurrentContext();
+        }
+        
         Thread.currentThread().setContextClassLoader(threadContextClassLoader);
         threadContextClassLoader = null;
     }
@@ -741,7 +790,7 @@ public class AbstractJsfTestContainer
      */
     protected boolean isScanAnnotations()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null)
         {
             return testConfig.scanAnnotations();
@@ -1247,6 +1296,7 @@ public class AbstractJsfTestContainer
 
     // Thread context class loader saved and restored after each test
     private ClassLoader threadContextClassLoader = null;
+    private Context jndiContext = null;
 
     // Servlet objects 
     protected MockServletConfig servletConfig = null;
@@ -1292,6 +1342,11 @@ public class AbstractJsfTestContainer
         this.facesInitializer = facesInitializer;
     }
     
+    protected Class<?> getTestJavaClass()
+    {
+        return testClass.getJavaClass();
+    }
+    
 
     // ------------------------------------------------------ Subclasses
 
@@ -1338,7 +1393,7 @@ public class AbstractJsfTestContainer
                     facesConfig = super.getAnnotationsFacesConfig(ectx, metadataComplete); 
                 }
 
-                ManagedBeans annoManagedBeans = testClass.getJavaClass().getAnnotation(ManagedBeans.class);
+                ManagedBeans annoManagedBeans = getTestJavaClass().getAnnotation(ManagedBeans.class);
                 if (annoManagedBeans != null)
                 {
                     if (facesConfig == null)
@@ -1360,7 +1415,7 @@ public class AbstractJsfTestContainer
                     }
                 }
 
-                PageBean annoPageBean = testClass.getJavaClass().getAnnotation(PageBean.class);
+                PageBean annoPageBean = getTestJavaClass().getAnnotation(PageBean.class);
                 if (annoPageBean != null)
                 {
                     if (facesConfig == null)
@@ -1434,10 +1489,10 @@ public class AbstractJsfTestContainer
         {
             List<FacesConfig> appConfigResources = super.getContextSpecifiedFacesConfig(ectx);
             
-            DeclareFacesConfig annoFacesConfig = testClass.getJavaClass().getAnnotation(DeclareFacesConfig.class);
+            DeclareFacesConfig annoFacesConfig = getTestJavaClass().getAnnotation(DeclareFacesConfig.class);
             if (annoFacesConfig != null)
             {
-                Logger log = Logger.getLogger(testClass.getName());
+                Logger log = Logger.getLogger(getTestJavaClass().getName());
                 try
                 {
                     for (String systemId : annoFacesConfig.value())

Propchange: myfaces/core/trunk/impl-test/src/main/resources/
------------------------------------------------------------------------------
    bugtraq:number = true

Propchange: myfaces/core/trunk/impl-test/src/test/
------------------------------------------------------------------------------
    bugtraq:number = true

Propchange: myfaces/core/trunk/impl-test/src/test/java/
------------------------------------------------------------------------------
    bugtraq:number = true

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesCDIRequestTestCase.java Mon Mar  3 01:03:45 2014
@@ -21,12 +21,12 @@ package org.apache.myfaces.mc.test.core;
 import javax.faces.FacesException;
 import javax.faces.context.ExternalContext;
 import javax.servlet.ServletContext;
+import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.spi.InjectionProvider;
 import org.apache.myfaces.spi.InjectionProviderException;
 import org.apache.myfaces.spi.InjectionProviderFactory;
 import org.apache.myfaces.spi.impl.CDIAnnotationDelegateInjectionProvider;
 import org.apache.myfaces.webapp.AbstractFacesInitializer;
-import org.apache.webbeans.servlet.WebBeansConfigurationListener;
 
 /**
  *
@@ -34,7 +34,8 @@ import org.apache.webbeans.servlet.WebBe
 public class AbstractMyFacesCDIRequestTestCase extends AbstractMyFacesRequestTestCase
 {
     
-    protected WebBeansConfigurationListener owbListener;
+    //protected WebBeansConfigurationListener owbListener;
+    private Object owbListener;
     protected InjectionProvider injectionProvider;
     
     @Override
@@ -48,8 +49,16 @@ public class AbstractMyFacesCDIRequestTe
     @Override
     protected void setUpServletListeners() throws Exception
     {
-        owbListener = new WebBeansConfigurationListener();
-        webContainer.subscribeListener(owbListener);
+        Class listenerClass = ClassUtils.classForName("org.apache.webbeans.servlet.WebBeansConfigurationListener");
+        if (listenerClass == null)
+        {
+            listenerClass = ClassUtils.classForName("org.jboss.weld.environment.servlet.Listener");
+        }
+        if (listenerClass != null)
+        {
+            owbListener = ClassUtils.newInstance(listenerClass);
+            webContainer.subscribeListener(owbListener);
+        }
         super.setUpServletListeners();
     }
 

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java Mon Mar  3 01:03:45 2014
@@ -56,6 +56,7 @@ import javax.faces.lifecycle.Lifecycle;
 import javax.faces.lifecycle.LifecycleFactory;
 import javax.faces.view.ViewDeclarationLanguage;
 import javax.faces.webapp.FacesServlet;
+import javax.naming.Context;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextEvent;
 import javax.servlet.http.HttpServletResponse;
@@ -71,7 +72,11 @@ import org.apache.myfaces.lifecycle.View
 import org.apache.myfaces.mc.test.core.annotation.DeclareFacesConfig;
 import org.apache.myfaces.mc.test.core.annotation.ManagedBeans;
 import org.apache.myfaces.mc.test.core.annotation.PageBean;
+import org.apache.myfaces.mc.test.core.annotation.TestConfig;
+import org.apache.myfaces.mc.test.core.mock.DefaultContext;
+import org.apache.myfaces.mc.test.core.mock.MockInitialContextFactory;
 import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.shared.util.ClassUtils;
 import org.apache.myfaces.spi.FacesConfigurationProvider;
 import org.apache.myfaces.spi.impl.DefaultFacesConfigurationProviderFactory;
 import org.apache.myfaces.spi.impl.NoInjectionAnnotationInjectionProvider;
@@ -155,11 +160,20 @@ public abstract class AbstractMyFacesTes
                         new URLClassLoader(new URL[0], this.getClass()
                                 .getClassLoader()));
         
-        jsfConfiguration = sharedConfiguration.get(this.getClass().getName());
+        jsfConfiguration = sharedConfiguration.get(getTestJavaClass().getName());
         if (jsfConfiguration == null)
         {
             jsfConfiguration = new SharedFacesConfiguration();
         }
+        
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        boolean enableJNDI = (testConfig != null) ? testConfig.enableJNDI() : true;
+        if (enableJNDI)
+        {
+            System.setProperty(Context.INITIAL_CONTEXT_FACTORY, MockInitialContextFactory.class.getName());
+            jndiContext = new DefaultContext();
+            MockInitialContextFactory.setCurrentContext(jndiContext);
+        }
 
         // Set up Servlet API Objects
         setUpServletObjects();
@@ -173,7 +187,7 @@ public abstract class AbstractMyFacesTes
         
         setUpFacesServlet();
         
-        sharedConfiguration.put(this.getClass().getName(), jsfConfiguration);
+        sharedConfiguration.put(getTestJavaClass().getName(), jsfConfiguration);
     }
     
     /**
@@ -258,6 +272,12 @@ public abstract class AbstractMyFacesTes
      */
     protected String getWebappResourcePath()
     {
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        if (testConfig != null && testConfig.webappResourcePath() != null &&
+            !"testClassResourcePackage".equals(testConfig.webappResourcePath()))
+        {
+            return testConfig.webappResourcePath();
+        }
         return this.getClass().getName().substring(0,
                 this.getClass().getName().lastIndexOf('.')).replace('.', '/')
                 + "/";
@@ -271,6 +291,13 @@ public abstract class AbstractMyFacesTes
      */
     protected ExpressionFactory createExpressionFactory()
     {
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        if (testConfig != null && testConfig.expressionFactory() != null &&
+            testConfig.expressionFactory().length() > 0)
+        {
+            return (ExpressionFactory) ClassUtils.newInstance(
+                testConfig.expressionFactory(), ExpressionFactory.class);
+        }
         return new MockExpressionFactory();
     }
     
@@ -371,6 +398,11 @@ public abstract class AbstractMyFacesTes
         
         FactoryFinder.releaseFactories();
         
+        if (jndiContext != null)
+        {
+            MockInitialContextFactory.clearCurrentContext();
+        }
+        
         Thread.currentThread().setContextClassLoader(threadContextClassLoader);
         threadContextClassLoader = null;
     }
@@ -681,6 +713,11 @@ public abstract class AbstractMyFacesTes
      */
     protected boolean isScanAnnotations()
     {
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
+        if (testConfig != null)
+        {
+            return testConfig.scanAnnotations();
+        }
         return false;
     }
     
@@ -1167,6 +1204,7 @@ public abstract class AbstractMyFacesTes
 
     // Thread context class loader saved and restored after each test
     private ClassLoader threadContextClassLoader = null;
+    private Context jndiContext = null;
 
     // Servlet objects 
     protected MockServletConfig servletConfig = null;
@@ -1185,6 +1223,12 @@ public abstract class AbstractMyFacesTes
     private static Map<String, SharedFacesConfiguration> sharedConfiguration =
         new ConcurrentHashMap<String, SharedFacesConfiguration>();
     private SharedFacesConfiguration jsfConfiguration;
+    
+    protected Class<?> getTestJavaClass()
+    {
+        return this.getClass();
+    }
+    
 
     // ------------------------------------------------------ Subclasses
 
@@ -1233,7 +1277,7 @@ public abstract class AbstractMyFacesTes
                     facesConfig = super.getAnnotationsFacesConfig(ectx, metadataComplete); 
                 }
 
-                ManagedBeans annoManagedBeans = testCase.getClass().getAnnotation(ManagedBeans.class);
+                ManagedBeans annoManagedBeans = getTestJavaClass().getAnnotation(ManagedBeans.class);
                 if (annoManagedBeans != null)
                 {
                     if (facesConfig == null)
@@ -1255,7 +1299,7 @@ public abstract class AbstractMyFacesTes
                     }
                 }
 
-                PageBean annoPageBean = testCase.getClass().getAnnotation(PageBean.class);
+                PageBean annoPageBean = getTestJavaClass().getAnnotation(PageBean.class);
                 if (annoPageBean != null)
                 {
                     if (facesConfig == null)
@@ -1329,10 +1373,10 @@ public abstract class AbstractMyFacesTes
         {
             List<FacesConfig> appConfigResources = super.getContextSpecifiedFacesConfig(ectx);
             
-            DeclareFacesConfig annoFacesConfig = testCase.getClass().getAnnotation(DeclareFacesConfig.class);
+            DeclareFacesConfig annoFacesConfig = getTestJavaClass().getAnnotation(DeclareFacesConfig.class);
             if (annoFacesConfig != null)
             {
-                Logger log = Logger.getLogger(testCase.getClass().getName());
+                Logger log = Logger.getLogger(getTestJavaClass().getName());
                 try
                 {
                     for (String systemId : annoFacesConfig.value())

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,37 @@
+/*
+ * 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.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 
+ */
+@Retention(value = RetentionPolicy.RUNTIME)
+@Target(value =
+{
+    ElementType.METHOD
+})
+public @interface BeforeJSFInit
+{
+    
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/BeforeJSFInit.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/annotation/TestConfig.java Mon Mar  3 01:03:45 2014
@@ -47,4 +47,6 @@ public @interface TestConfig
     
     String servletPath() default "/faces";
     
+    boolean enableJNDI() default true;
+    
 }

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,553 @@
+/*
+ * 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.mock;
+
+import javax.naming.Binding;
+import javax.naming.CompositeName;
+import javax.naming.Context;
+import javax.naming.LinkRef;
+import javax.naming.Name;
+import javax.naming.NameClassPair;
+import javax.naming.NameNotFoundException;
+import javax.naming.NameParser;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NotContextException;
+import javax.naming.OperationNotSupportedException;
+import javax.naming.Reference;
+import javax.naming.spi.NamingManager;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * A simple spring based JNDI context which is mutable
+ *
+ * NOTE: Code copied from org.apache.xbean.spring.jndi.DefaultContext
+ *
+ * @version $Revision: 657 $
+ */
+public class DefaultContext implements Context, Serializable
+{
+
+    private static final long serialVersionUID = -5754338187296859149L;
+    protected static final NameParser NAMED_PARSER = new NameParserImpl();
+
+    private boolean freeze = false;
+
+    protected final Hashtable environment;        // environment for this context
+    protected final Map bindings;         // bindings at my level
+    protected final Map treeBindings;     // all bindings under me
+
+    private boolean frozen = false;
+    private String nameInNamespace = "";
+    public static final String SEPARATOR = "/";
+
+    public DefaultContext()
+    {
+        environment = new Hashtable();
+        bindings = new HashMap();
+        treeBindings = new HashMap();
+    }
+
+    public DefaultContext(Hashtable env)
+    {
+        if (env == null)
+        {
+            this.environment = new Hashtable();
+        }
+        else
+        {
+            this.environment = new Hashtable(env);
+        }
+        this.bindings = new HashMap();
+        this.treeBindings = new HashMap();
+    }
+
+    public DefaultContext(Hashtable environment, Map bindings)
+    {
+        if (environment == null)
+        {
+            this.environment = new Hashtable();
+        }
+        else
+        {
+            this.environment = new Hashtable(environment);
+        }
+        this.bindings = bindings;
+        treeBindings = new HashMap();
+        frozen = true;
+    }
+
+    public DefaultContext(Hashtable environment, Map bindings, String nameInNamespace)
+    {
+        this(environment, bindings);
+        this.nameInNamespace = nameInNamespace;
+    }
+
+    protected DefaultContext(DefaultContext clone, Hashtable env)
+    {
+        this.bindings = clone.bindings;
+        this.treeBindings = clone.treeBindings;
+        this.environment = new Hashtable(env);
+    }
+
+    protected DefaultContext(DefaultContext clone, Hashtable env, String nameInNamespace)
+    {
+        this(clone, env);
+        this.nameInNamespace = nameInNamespace;
+    }
+
+    public Object addToEnvironment(String propName, Object propVal) throws NamingException
+    {
+        return environment.put(propName, propVal);
+    }
+
+    public Hashtable getEnvironment() throws NamingException
+    {
+        return (Hashtable) environment.clone();
+    }
+
+    public Object removeFromEnvironment(String propName) throws NamingException
+    {
+        return environment.remove(propName);
+    }
+
+    public Object lookup(String name) throws NamingException
+    {
+        if (name.length() == 0)
+        {
+            return this;
+        }
+        Object result = treeBindings.get(name);
+        if (result == null)
+        {
+            result = bindings.get(name);
+        }
+        if (result == null)
+        {
+            int pos = name.indexOf(':');
+            if (pos > 0)
+            {
+                String scheme = name.substring(0, pos);
+                Context ctx = NamingManager.getURLContext(scheme, environment);
+                if (ctx == null)
+                {
+                    throw new NamingException("scheme " + scheme + " not recognized");
+                }
+                return ctx.lookup(name);
+            }
+            else
+            {
+                // Split out the first name of the path
+                // and look for it in the bindings map.
+                CompositeName path = new CompositeName(name);
+
+                if (path.size() == 0)
+                {
+                    return this;
+                }
+                else
+                {
+                    String first = path.get(0);
+                    Object obj = bindings.get(first);
+                    if (obj == null)
+                    {
+                        throw new NameNotFoundException(name);
+                    }
+                    else if (obj instanceof Context && path.size() > 1)
+                    {
+                        Context subContext = (Context) obj;
+                        obj = subContext.lookup(path.getSuffix(1));
+                    }
+                    return obj;
+                }
+            }
+        }
+        if (result instanceof LinkRef)
+        {
+            LinkRef ref = (LinkRef) result;
+            result = lookup(ref.getLinkName());
+        }
+        if (result instanceof Reference)
+        {
+            try
+            {
+                result = NamingManager.getObjectInstance(result, null, null, this.environment);
+            }
+            catch (NamingException e)
+            {
+                throw e;
+            }
+            catch (Exception e)
+            {
+                throw (NamingException) new NamingException("could not look up : " + name).initCause(e);
+            }
+        }
+        if (result instanceof DefaultContext)
+        {
+            String prefix = getNameInNamespace();
+            if (prefix.length() > 0)
+            {
+                prefix = prefix + SEPARATOR;
+            }
+            result = new DefaultContext((DefaultContext) result, environment, prefix + name);
+        }
+        return result;
+    }
+
+    public Object lookup(Name name) throws NamingException
+    {
+        return lookup(name.toString());
+    }
+
+    public Object lookupLink(String name) throws NamingException
+    {
+        return lookup(name);
+    }
+
+    public Name composeName(Name name, Name prefix) throws NamingException
+    {
+        Name result = (Name) prefix.clone();
+        result.addAll(name);
+        return result;
+    }
+
+    public String composeName(String name, String prefix) throws NamingException
+    {
+        CompositeName result = new CompositeName(prefix);
+        result.addAll(new CompositeName(name));
+        return result.toString();
+    }
+
+    public NamingEnumeration list(String name) throws NamingException
+    {
+        Object o = lookup(name);
+        if (o == this)
+        {
+            return new DefaultContext.ListEnumeration();
+        }
+        else if (o instanceof Context)
+        {
+            return ((Context) o).list("");
+        }
+        else
+        {
+            throw new NotContextException();
+        }
+    }
+
+    public NamingEnumeration listBindings(String name) throws NamingException
+    {
+        Object o = lookup(name);
+        if (o == this)
+        {
+            return new DefaultContext.ListBindingEnumeration();
+        }
+        else if (o instanceof Context)
+        {
+            return ((Context) o).listBindings("");
+        }
+        else
+        {
+            throw new NotContextException();
+        }
+    }
+
+    public Object lookupLink(Name name) throws NamingException
+    {
+        return lookupLink(name.toString());
+    }
+
+    public NamingEnumeration list(Name name) throws NamingException
+    {
+        return list(name.toString());
+    }
+
+    public NamingEnumeration listBindings(Name name) throws NamingException
+    {
+        return listBindings(name.toString());
+    }
+
+    public void bind(Name name, Object value) throws NamingException
+    {
+        bind(name.toString(), value);
+    }
+
+    public void bind(String name, Object value) throws NamingException
+    {
+        checkFrozen();
+        internalBind(name, value);
+    }
+
+    public void close() throws NamingException
+    {
+        // ignore
+    }
+
+    public Context createSubcontext(Name name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public Context createSubcontext(String name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public void destroySubcontext(Name name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public void destroySubcontext(String name) throws NamingException
+    {
+        throw new OperationNotSupportedException();
+    }
+
+    public String getNameInNamespace() throws NamingException
+    {
+        return nameInNamespace;
+    }
+
+    public NameParser getNameParser(Name name) throws NamingException
+    {
+        return NAMED_PARSER;
+    }
+
+    public NameParser getNameParser(String name) throws NamingException
+    {
+        return NAMED_PARSER;
+    }
+
+    public void rebind(Name name, Object value) throws NamingException
+    {
+        rebind(name.toString(), value);
+    }
+
+    public void rebind(String name, Object value) throws NamingException
+    {
+        checkFrozen();
+        internalBind(name, value, true);
+    }
+
+    public void rename(Name oldName, Name newName) throws NamingException
+    {
+        checkFrozen();
+        Object value = lookup(oldName);
+        unbind(oldName);
+        bind(newName, value);
+    }
+
+    public void rename(String oldName, String newName) throws NamingException
+    {
+        Object value = lookup(oldName);
+        unbind(oldName);
+        bind(newName, value);
+    }
+
+    public void unbind(Name name) throws NamingException
+    {
+        unbind(name.toString());
+    }
+
+    public void unbind(String name) throws NamingException
+    {
+        checkFrozen();
+        internalBind(name, null, true);
+    }
+
+    private abstract class LocalNamingEnumeration implements NamingEnumeration
+    {
+
+        private Iterator i = bindings.entrySet().iterator();
+
+        public boolean hasMore() throws NamingException
+        {
+            return i.hasNext();
+        }
+
+        public boolean hasMoreElements()
+        {
+            return i.hasNext();
+        }
+
+        protected Map.Entry getNext()
+        {
+            return (Map.Entry) i.next();
+        }
+
+        public void close() throws NamingException
+        {
+        }
+    }
+
+    private class ListEnumeration extends DefaultContext.LocalNamingEnumeration
+    {
+
+        public Object next() throws NamingException
+        {
+            return nextElement();
+        }
+
+        public Object nextElement()
+        {
+            Map.Entry entry = getNext();
+            return new NameClassPair((String) entry.getKey(), entry.getValue().getClass().getName());
+        }
+    }
+
+    private class ListBindingEnumeration extends DefaultContext.LocalNamingEnumeration
+    {
+
+        public Object next() throws NamingException
+        {
+            return nextElement();
+        }
+
+        public Object nextElement()
+        {
+            Map.Entry entry = getNext();
+            return new Binding((String) entry.getKey(), entry.getValue());
+        }
+    }
+
+    public Map getEntries()
+    {
+        return new HashMap(bindings);
+    }
+
+    public void setEntries(Map entries) throws NamingException
+    {
+        if (entries != null)
+        {
+            for (Iterator iter = entries.entrySet().iterator(); iter.hasNext();)
+            {
+                Map.Entry entry = (Map.Entry) iter.next();
+                String name = (String) entry.getKey();
+                Object value = entry.getValue();
+                internalBind(name, value);
+            }
+        }
+    }
+
+    public boolean isFreeze()
+    {
+        return freeze;
+    }
+
+    public void setFreeze(boolean freeze)
+    {
+        this.freeze = freeze;
+    }
+
+    /**
+     * internalBind is intended for use only during setup or possibly by suitably synchronized superclasses. It binds
+     * every possible lookup into a map in each context. To do this, each context strips off one name segment and if
+     * necessary creates a new context for it. Then it asks that context to bind the remaining name. It returns a map
+     * containing all the bindings from the next context, plus the context it just created (if it in fact created it).
+     * (the names are suitably extended by the segment originally lopped off).
+     *
+     * @param name
+     * @param value
+     * @return
+     * @throws javax.naming.NamingException
+     */
+    protected Map internalBind(String name, Object value) throws NamingException
+    {
+        return internalBind(name, value, false);
+
+    }
+
+    protected Map internalBind(String name, Object value, boolean allowRebind) throws NamingException
+    {
+
+        if (name == null || name.length() == 0)
+        {
+            throw new NamingException("Invalid Name " + name);
+        }
+        if (frozen)
+        {
+            throw new NamingException("Read only");
+        }
+
+        Map newBindings = new HashMap();
+        int pos = name.indexOf('/');
+        if (pos == -1)
+        {
+            Object oldValue = treeBindings.put(name, value);
+            if (!allowRebind && oldValue != null)
+            {
+                throw new NamingException("Something already bound at " + name);
+            }
+            bindings.put(name, value);
+            newBindings.put(name, value);
+        }
+        else
+        {
+            String segment = name.substring(0, pos);
+
+            if (segment == null || segment.length() == 0)
+            {
+                throw new NamingException("Invalid segment " + segment);
+            }
+            Object o = treeBindings.get(segment);
+            if (o == null)
+            {
+                o = newContext();
+                treeBindings.put(segment, o);
+                bindings.put(segment, o);
+                newBindings.put(segment, o);
+            }
+            else if (!(o instanceof DefaultContext))
+            {
+                throw new NamingException("Something already bound where a subcontext should go");
+            }
+            DefaultContext defaultContext = (DefaultContext) o;
+            String remainder = name.substring(pos + 1);
+            Map subBindings = defaultContext.internalBind(remainder, value, allowRebind);
+            for (Iterator iterator = subBindings.entrySet().iterator(); iterator.hasNext();)
+            {
+                Map.Entry entry = (Map.Entry) iterator.next();
+                String subName = segment + "/" + (String) entry.getKey();
+                Object bound = entry.getValue();
+                treeBindings.put(subName, bound);
+                newBindings.put(subName, bound);
+            }
+        }
+        return newBindings;
+    }
+
+    protected void checkFrozen() throws OperationNotSupportedException
+    {
+        if (isFreeze())
+        {
+            throw new OperationNotSupportedException("JNDI context is frozen!");
+        }
+    }
+
+    protected DefaultContext newContext()
+    {
+        return new DefaultContext();
+    }
+
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/DefaultContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,63 @@
+/*
+ * 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.mock;
+
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+
+/**
+ * Mock per-thread implementation of InitialContextFactory
+ *
+ */
+public class MockInitialContextFactory implements InitialContextFactory
+{
+
+    private static ThreadLocal<Context> currentInstance = new ThreadLocal<Context>();
+
+    public Context getInitialContext(Hashtable<?, ?> environment)
+        throws NamingException
+    {
+        return currentInstance.get();
+    }
+    
+    public static void setCurrentContext(Context context)
+    {
+        currentInstance.set(context);
+    }
+
+    public static void clearCurrentContext()
+    {
+        currentInstance.remove();
+    }    
+
+    public static void bind(String name, Object obj)
+    {
+        try
+        {
+            currentInstance.get().bind(name, obj);
+        }
+        catch (NamingException e)
+        { // can't happen.
+            throw new RuntimeException(e);
+        }
+    }
+    
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/MockInitialContextFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java?rev=1573413&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java (added)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java Mon Mar  3 01:03:45 2014
@@ -0,0 +1,40 @@
+/*
+ * 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.mock;
+
+import javax.naming.CompositeName;
+import javax.naming.Name;
+import javax.naming.NameParser;
+import javax.naming.NamingException;
+
+/**
+ * A default implementation of {@link NameParser}
+ *
+ * NOTE: Code copied from org.apache.xbean.spring.jndi.NameParserImpl
+ *
+ * @version $Revision: 1.2 $
+ */
+public class NameParserImpl implements NameParser
+{
+
+    public Name parse(String name) throws NamingException
+    {
+        return new CompositeName(name);
+    }
+}

Propchange: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/mock/NameParserImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java?rev=1573413&r1=1573412&r2=1573413&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/runner/AbstractJsfRequestTestContainer.java Mon Mar  3 01:03:45 2014
@@ -232,7 +232,7 @@ public class AbstractJsfRequestTestConta
     
     protected String getContextPath()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null)
         {
             return testConfig.contextPath();
@@ -242,7 +242,7 @@ public class AbstractJsfRequestTestConta
     
     protected String getServletPath()
     {
-        TestConfig testConfig = testClass.getJavaClass().getAnnotation(TestConfig.class);
+        TestConfig testConfig = getTestJavaClass().getAnnotation(TestConfig.class);
         if (testConfig != null)
         {
             return testConfig.servletPath();