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.test.utils;
20  
21  import java.util.Map;
22  
23  import javax.faces.component.UIComponent;
24  import javax.faces.context.FacesContext;
25  
26  import org.apache.myfaces.test.mock.MockResponseWriter;
27  
28  /**
29   * This is a utility class used in unit test cases to check if
30   * a component's attributes are rendered properly.
31   */
32  public class HtmlCheckAttributesUtil 
33  {
34      /**
35       * This method adds all elements of attrs to the attributes map of component.
36       * @param component The component to add the attributes to.
37       * @param attrs     The attributes to be added to the component.
38       */
39      private static void addBaseAttributes(UIComponent component, HtmlRenderedAttr[] attrs) 
40      {
41          Map map = component.getAttributes();
42          for(int i = 0; i < attrs.length; i++) 
43          {
44              HtmlRenderedAttr attr = attrs[i];
45              map.put(attr.getName(), attr.getValue());
46          }
47      }
48      
49      /**
50       * Iterates through all elements of attrs to check if they are only rendered once in output.
51       * @param attrs      The attributes to be checked.
52       * @param output     The html output of the component's renderer.
53       * @throws Exception
54       */
55      public static void checkRenderedAttributes(HtmlRenderedAttr[] attrs, String output) throws Exception 
56      {
57          for(int i = 0; i < attrs.length; i++) 
58          {
59              //assertContainsOnlyOnce(attrs[i], output);
60              checkAttributeOccurrences(attrs[i], output);
61          }
62      }
63      
64      /**
65       * This method adds all attributes from attrs into the component.  After adding the attributes,
66       * it calls the encodeAll() method of the component.  The html generated from the component's
67       * renderer will be checked to see if the attributes have been rendered correctly.
68       * @param component  The component whose attributes will be tested.
69       * @param context    
70       * @param writer     The ResponseWriter used by the renderer to output the html generated.
71       * @param attrs      An array of attributes which will be tested.
72       * @throws Exception
73       */
74      public static void checkRenderedAttributes(
75              UIComponent component, 
76              FacesContext context, 
77              MockResponseWriter writer,
78              HtmlRenderedAttr[] attrs) throws Exception 
79      {
80          
81          addBaseAttributes(component, attrs);
82          component.encodeAll(context);
83          context.renderResponse();
84          checkRenderedAttributes(attrs, writer.getWriter().toString());
85      }
86      
87      /**
88       * Checks the attrs array if it has elements which were rendered incorrectly.
89       * @param attrs The attributes to be checked.
90       * @return True if there are attributes not rendered correctly.
91       */
92      public static boolean hasFailedAttrRender(HtmlRenderedAttr[] attrs) 
93      {
94          for(int i = 0; i < attrs.length; i++) 
95          {
96              if(!attrs[i].isRenderSuccessful())
97              {
98                  return true;
99              }
100         }
101         return false;
102     }
103     
104     /**
105      * Constructs an error message string detailing which attributes were not rendered
106      * and which attributes were rendered more than once.
107      * @param attrs   The attributes to be tested.
108      * @param actual  The html generated by the renderer.
109      * @return The error message.
110      */
111     public static String constructErrorMessage(HtmlRenderedAttr[] attrs, String actual) 
112     {
113         StringBuffer messgBuffer = new StringBuffer();
114         for(int i = 0; i < attrs.length; i++) 
115         {
116             if(attrs[i].getErrorCode() == HtmlRenderedAttr.RENDERED_MORE_TIMES_THAN_EXPECTED) 
117             {
118                 messgBuffer.append(attrs[i].getName()).append(" (");
119                 messgBuffer.append(attrs[i].getExpectedHtml()).append(") was rendered more times (");
120                 messgBuffer.append(attrs[i].getActualOccurrences()).append(") than expected (");
121                 messgBuffer.append(attrs[i].getExpectedOccurrences()).append(").");
122                 messgBuffer.append(System.getProperty("line.separator"));
123             } 
124             else if(attrs[i].getErrorCode() == HtmlRenderedAttr.RENDERED_LESS_TIMES_THAN_EXPECTED)
125             {
126                 messgBuffer.append(attrs[i].getName()).append(" (");
127                 messgBuffer.append(attrs[i].getExpectedHtml()).append(") was rendered less times (");
128                 messgBuffer.append(attrs[i].getActualOccurrences()).append(") than expected (");
129                 messgBuffer.append(attrs[i].getExpectedOccurrences()).append(").");
130                 messgBuffer.append(System.getProperty("line.separator"));
131             }
132         }
133         messgBuffer.append("Actual HTML: ").append(actual);
134         return messgBuffer.toString();
135     }
136     
137     /**
138      * Checks if the occurrence of the rendered attribute in the html
139      * generated by the renderer is equal to the number of times expected.
140      * @param attr   The attribute to be tested.
141      * @param actual The html generated by the renderer.
142      */
143     private static void checkAttributeOccurrences(HtmlRenderedAttr attr, String actual)
144     {
145         String expectedHtml = attr.getExpectedHtml();
146         
147         int index;
148         int offset = 0;
149         while((index=actual.indexOf(expectedHtml,offset)) != -1) 
150         {
151             attr.increaseActualOccurrences();
152             if(attr.getActualOccurrences() > attr.getExpectedOccurrences()) 
153             {
154                 attr.setErrorCode(HtmlRenderedAttr.RENDERED_MORE_TIMES_THAN_EXPECTED);
155                 return;
156             } 
157 
158             offset += index + expectedHtml.length();
159         }
160         
161         if(attr.getActualOccurrences() < attr.getExpectedOccurrences()) 
162         {
163             attr.setErrorCode(HtmlRenderedAttr.RENDERED_LESS_TIMES_THAN_EXPECTED);
164         } 
165         else 
166         {
167             attr.setRenderSuccessful(true);
168         }
169     }
170     
171     public static HtmlRenderedAttr[] generateBasicAttrs() {
172         HtmlRenderedAttr[] attrs = {
173             //_AccesskeyProperty
174             new HtmlRenderedAttr("accesskey"),
175             //_UniversalProperties
176             new HtmlRenderedAttr("dir"), 
177             new HtmlRenderedAttr("lang"), 
178             new HtmlRenderedAttr("title"),
179             new HtmlRenderedAttr("role"),
180             //_FocusBlurProperties
181             new HtmlRenderedAttr("onfocus"), 
182             new HtmlRenderedAttr("onblur"),
183             //_ChangeSelectProperties
184             new HtmlRenderedAttr("onchange"), 
185             new HtmlRenderedAttr("onselect"),
186             //_EventProperties
187             new HtmlRenderedAttr("onclick"), 
188             new HtmlRenderedAttr("ondblclick"), 
189             new HtmlRenderedAttr("onkeydown"), 
190             new HtmlRenderedAttr("onkeypress"),
191             new HtmlRenderedAttr("onkeyup"), 
192             new HtmlRenderedAttr("onmousedown"), 
193             new HtmlRenderedAttr("onmousemove"), 
194             new HtmlRenderedAttr("onmouseout"),
195             new HtmlRenderedAttr("onmouseover"), 
196             new HtmlRenderedAttr("onmouseup"),
197             //_StyleProperties
198             new HtmlRenderedAttr("style"), 
199             new HtmlRenderedAttr("styleClass", "styleClass", "class=\"styleClass\""),
200             //_TabindexProperty
201             new HtmlRenderedAttr("tabindex")
202         };
203         
204         return attrs;
205     }
206     
207     public static HtmlRenderedAttr[] generateAttrsNotRenderedForReadOnly() 
208     {
209         HtmlRenderedAttr[] attrs = {
210             //_AccesskeyProperty
211             new HtmlRenderedAttr("accesskey", 0),
212             //_FocusBlurProperties
213             new HtmlRenderedAttr("onfocus", 0), 
214             new HtmlRenderedAttr("onblur", 0),
215             //_ChangeSelectProperties
216             new HtmlRenderedAttr("onchange", 0), 
217             new HtmlRenderedAttr("onselect", 0),
218             //_TabindexProperty
219             new HtmlRenderedAttr("tabindex", 0)
220         };
221         return attrs;
222     }
223     
224     public static HtmlRenderedAttr[] generateBasicReadOnlyAttrs() {
225         HtmlRenderedAttr[] attrs = {
226             //_UniversalProperties
227             new HtmlRenderedAttr("dir"), 
228             new HtmlRenderedAttr("lang"), 
229             new HtmlRenderedAttr("title"),
230             new HtmlRenderedAttr("role"),
231             //_EventProperties
232             new HtmlRenderedAttr("onclick"), 
233             new HtmlRenderedAttr("ondblclick"), 
234             new HtmlRenderedAttr("onkeydown"), 
235             new HtmlRenderedAttr("onkeypress"),
236             new HtmlRenderedAttr("onkeyup"), 
237             new HtmlRenderedAttr("onmousedown"), 
238             new HtmlRenderedAttr("onmousemove"), 
239             new HtmlRenderedAttr("onmouseout"),
240             new HtmlRenderedAttr("onmouseover"), 
241             new HtmlRenderedAttr("onmouseup"),
242             //_StyleProperties
243             new HtmlRenderedAttr("style"), 
244             new HtmlRenderedAttr("styleClass", "styleClass", "class=\"styleClass\""),
245         };
246         
247         return attrs;
248     }
249 }