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             //_FocusBlurProperties
180             new HtmlRenderedAttr("onfocus"), 
181             new HtmlRenderedAttr("onblur"),
182             //_ChangeSelectProperties
183             new HtmlRenderedAttr("onchange"), 
184             new HtmlRenderedAttr("onselect"),
185             //_EventProperties
186             new HtmlRenderedAttr("onclick"), 
187             new HtmlRenderedAttr("ondblclick"), 
188             new HtmlRenderedAttr("onkeydown"), 
189             new HtmlRenderedAttr("onkeypress"),
190             new HtmlRenderedAttr("onkeyup"), 
191             new HtmlRenderedAttr("onmousedown"), 
192             new HtmlRenderedAttr("onmousemove"), 
193             new HtmlRenderedAttr("onmouseout"),
194             new HtmlRenderedAttr("onmouseover"), 
195             new HtmlRenderedAttr("onmouseup"),
196             //_StyleProperties
197             new HtmlRenderedAttr("style"), 
198             new HtmlRenderedAttr("styleClass", "styleClass", "class=\"styleClass\""),
199             //_TabindexProperty
200             new HtmlRenderedAttr("tabindex")
201         };
202         
203         return attrs;
204     }
205     
206     public static HtmlRenderedAttr[] generateAttrsNotRenderedForReadOnly() 
207     {
208         HtmlRenderedAttr[] attrs = {
209             //_AccesskeyProperty
210             new HtmlRenderedAttr("accesskey", 0),
211             //_FocusBlurProperties
212             new HtmlRenderedAttr("onfocus", 0), 
213             new HtmlRenderedAttr("onblur", 0),
214             //_ChangeSelectProperties
215             new HtmlRenderedAttr("onchange", 0), 
216             new HtmlRenderedAttr("onselect", 0),
217             //_TabindexProperty
218             new HtmlRenderedAttr("tabindex", 0)
219         };
220         return attrs;
221     }
222     
223     public static HtmlRenderedAttr[] generateBasicReadOnlyAttrs() {
224         HtmlRenderedAttr[] attrs = {
225             //_UniversalProperties
226             new HtmlRenderedAttr("dir"), 
227             new HtmlRenderedAttr("lang"), 
228             new HtmlRenderedAttr("title"),
229             //_EventProperties
230             new HtmlRenderedAttr("onclick"), 
231             new HtmlRenderedAttr("ondblclick"), 
232             new HtmlRenderedAttr("onkeydown"), 
233             new HtmlRenderedAttr("onkeypress"),
234             new HtmlRenderedAttr("onkeyup"), 
235             new HtmlRenderedAttr("onmousedown"), 
236             new HtmlRenderedAttr("onmousemove"), 
237             new HtmlRenderedAttr("onmouseout"),
238             new HtmlRenderedAttr("onmouseover"), 
239             new HtmlRenderedAttr("onmouseup"),
240             //_StyleProperties
241             new HtmlRenderedAttr("style"), 
242             new HtmlRenderedAttr("styleClass", "styleClass", "class=\"styleClass\""),
243         };
244         
245         return attrs;
246     }
247 }