View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.myfaces.mc.test.core.runner;
20  
21  import java.lang.reflect.Field;
22  import java.util.List;
23  import javax.faces.context.FacesContext;
24  import org.apache.myfaces.mc.test.core.annotation.TestContainer;
25  import org.apache.myfaces.spi.InjectionProvider;
26  import org.apache.myfaces.spi.InjectionProviderFactory;
27  import org.junit.runners.BlockJUnit4ClassRunner;
28  import org.junit.runners.model.FrameworkField;
29  import org.junit.runners.model.FrameworkMethod;
30  import org.junit.runners.model.InitializationError;
31  import org.junit.runners.model.Statement;
32  import org.junit.runners.model.TestClass;
33  
34  /**
35   *
36   */
37  public class MyFacesTestRunner extends BlockJUnit4ClassRunner
38  {
39  
40      public MyFacesTestRunner(Class<?> klass) throws InitializationError
41      {
42          super(klass);
43          
44          // Annotation processing goes here.
45      }
46  
47      @Override
48      protected Statement withAfters(FrameworkMethod method, Object target, Statement statement)
49      {
50          return new ContainerAwareMethodInvoker(getTestClass(), method, 
51              super.withAfters(method, target, statement), target);
52      }
53  
54      @Override
55      protected Statement withAfterClasses(Statement statement)
56      {
57          return new ClearSharedFacesConfiguration(statement, getTestClass());
58      }
59  
60      private static class ContainerAwareMethodInvoker extends Statement
61      {
62          private final TestClass testClass;
63          private final FrameworkMethod method;
64          private final Object originalTarget;
65          private final Statement defaultStatement;
66  
67          public ContainerAwareMethodInvoker(TestClass testClass,
68              FrameworkMethod method, Statement defaultStatement, Object originalTarget)
69          {
70              this.testClass = testClass;
71              this.method = method;
72              this.defaultStatement = defaultStatement;
73              this.originalTarget = originalTarget;
74          }
75          
76          @Override
77          public void evaluate() throws Throwable
78          {
79              MyFacesContainer currentTestContext = new MyFacesContainer(testClass);
80  
81              //Inject MyFacesContainer using @TestContainer
82              List<FrameworkField> fields = testClass.getAnnotatedFields(TestContainer.class);
83              if (fields != null && !fields.isEmpty())
84              {
85                  for (FrameworkField field : fields)
86                  {
87                      Field f = field.getField();
88                      if (f.getType().equals(MyFacesContainer.class))
89                      {
90                          f.setAccessible(true);
91                          f.set(originalTarget, currentTestContext);
92                      }
93                  }
94              }
95              
96              currentTestContext.setUp(this.originalTarget);
97              
98              FacesContext facesContext = null;
99              InjectionProvider injectionProvider = null;
100             Object testCaseCreationMetadata = null;
101             try
102             {
103                 facesContext = currentTestContext.getFacesInitializer().
104                     initStartupFacesContext(currentTestContext.servletContext);
105                 
106                 InjectionProviderFactory ipf = InjectionProviderFactory.
107                     getInjectionProviderFactory(facesContext.getExternalContext());
108                 injectionProvider = ipf.getInjectionProvider(
109                     facesContext.getExternalContext());
110                 
111                 if (injectionProvider != null)
112                 {
113                     testCaseCreationMetadata = injectionProvider.inject(originalTarget);
114                     injectionProvider.postConstruct(originalTarget, testCaseCreationMetadata);
115                 }
116             }
117             finally
118             {
119                 currentTestContext.getFacesInitializer().destroyStartupFacesContext(facesContext);
120             }
121             try
122             {
123                 defaultStatement.evaluate();
124             }
125             finally
126             {
127                 facesContext = currentTestContext.getFacesInitializer().
128                     initShutdownFacesContext(currentTestContext.servletContext);
129 
130                 if (injectionProvider != null)
131                 {
132                     injectionProvider.preDestroy(originalTarget, testCaseCreationMetadata);
133                 }
134                 
135                 currentTestContext.getFacesInitializer().destroyShutdownFacesContext(facesContext);
136                 
137                 currentTestContext.tearDown();
138             }
139         }
140     }
141     
142     private static class ClearSharedFacesConfiguration extends Statement
143     {
144         private final Statement defaultStatement;
145         private final TestClass testClass;
146 
147         public ClearSharedFacesConfiguration(Statement defaultStatement, TestClass testClass)
148         {
149             this.defaultStatement = defaultStatement;
150             this.testClass = testClass;
151         }
152 
153         @Override
154         public void evaluate() throws Throwable
155         {
156             defaultStatement.evaluate();
157             
158             AbstractJsfTestContainer.tearDownClass(testClass.getJavaClass());
159         }
160         
161     }
162 
163 }