View Javadoc

1   package fit;
2   
3   // Copyright (c) 2002-2005 Cunningham & Cunningham, Inc.
4   // Released under the terms of the GNU General Public License version 2 or later.
5   
6   import java.io.*;
7   import java.util.*;
8   import java.lang.reflect.*;
9   import java.text.DateFormat;
10  
11  import net.sourceforge.xmlfit.fit.stepper.gui.DebuggerFrame;
12  
13  public class Fixture {
14      
15      private static final String FIT_DEBUGMODE = "fit.debugmode";
16      private static boolean debugMode = false;
17      
18      static
19      {
20        String property = System.getProperty(FIT_DEBUGMODE);
21        if(property != null && property.equals("true"))
22        {
23          debugMode = true;
24        }
25      }
26    
27      public Map summary = new HashMap();
28      public Counts counts = new Counts();
29      protected String[] args;
30      
31      public class RunTime {
32          long start = System.currentTimeMillis();
33          long elapsed = 0;
34  
35          public String toString() {
36              elapsed = (System.currentTimeMillis()-start);
37              if (elapsed > 600000) {
38                  return d(3600000)+":"+d(600000)+d(60000)+":"+d(10000)+d(1000);
39              } else {
40                  return d(60000)+":"+d(10000)+d(1000)+"."+d(100)+d(10);
41              }
42          }
43  
44          String d(long scale) {
45              long report = elapsed / scale;
46              elapsed -= report * scale;
47              return Long.toString(report);
48          }
49      }
50  
51  
52  
53      // Traversal //////////////////////////
54      private static DebuggerFrame frame = new DebuggerFrame();
55      
56  	/* Altered by Rick Mugridge to dispatch on the first Fixture */
57      public void doTables(Parse tables) {
58          if(debugMode)
59            frame.initTabeles(tables);
60        
61          summary.put("run date", new Date());
62          summary.put("run elapsed time", new RunTime());
63          if (tables != null) {
64          	Parse fixtureName = fixtureName(tables);
65              if (fixtureName != null) {
66                  try {
67                      Fixture fixture = getLinkedFixtureWithArgs(tables);
68                      fixture.interpretTables(tables);
69                  } catch (Exception e) {
70                      exception (fixtureName, e);
71                      interpretFollowingTables(tables);
72                  }
73              }
74          }
75      }
76  
77      /* Added by Rick Mugridge to allow a dispatch into DoFixture */
78      protected void interpretTables(Parse tables) {
79    		try { // Don't create the first fixture again, because creation may do something important.
80    			getArgsForTable(tables); // get them again for the new fixture object
81    			doTable(tables);
82    		} catch (Exception ex) {
83    			exception(fixtureName(tables), ex);
84    			return;
85    		}
86    		interpretFollowingTables(tables);
87    	}
88  
89      /* Added by Rick Mugridge */
90      private void interpretFollowingTables(Parse tables) {
91          //listener.tableFinished(tables);
92              tables = tables.more;
93          while (tables != null) {
94              Parse fixtureName = fixtureName(tables);
95              if (fixtureName != null) {
96                  try {
97                      Fixture fixture = getLinkedFixtureWithArgs(tables);
98                      fixture.doTable(tables);
99                  } catch (Throwable e) {
100                     exception(fixtureName, e);
101 		        }
102 		    }
103             //listener.tableFinished(tables);
104             tables = tables.more;
105         }
106     }
107 
108     /* Added from FitNesse*/
109 	protected Fixture getLinkedFixtureWithArgs(Parse tables) throws Exception {
110 		Parse header = tables.at(0, 0, 0);
111         Fixture fixture = loadFixture(header.text());
112 		fixture.counts = counts;
113 		fixture.summary = summary;
114 		fixture.getArgsForTable(tables);
115 		return fixture;
116 	}
117 	
118 	public Parse fixtureName(Parse tables) {
119 		return tables.at(0, 0, 0);
120 	}
121 
122 	public Fixture loadFixture(String fixtureName)
123 	throws InstantiationException, IllegalAccessException {
124 		String notFound = "The fixture \"" + fixtureName + "\" was not found.";
125 		try {
126 		  ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
127 		  Class<?> fixtureClass = contextClassLoader.loadClass(fixtureName);
128 			return (Fixture) fixtureClass.newInstance();
129 		}
130 		catch (ClassCastException e) {
131 			throw new RuntimeException("\"" + fixtureName + "\" was found, but it's not a fixture.", e);
132 		}
133 		catch (ClassNotFoundException e) {
134 			throw new RuntimeException(notFound, e);
135 		}
136 		catch (NoClassDefFoundError e) {
137 			throw new RuntimeException(notFound, e);
138 		}
139 	}
140 
141 	/* Added by Rick Mugridge, from FitNesse */
142 	protected void getArgsForTable(Parse table) {
143 	    ArrayList argumentList = new ArrayList();
144 	    Parse parameters = table.parts.parts.more;
145 	    for (; parameters != null; parameters = parameters.more)
146 	        argumentList.add(parameters.text());
147 	    args = (String[]) argumentList.toArray(new String[0]);
148 	}
149 
150     public void doTable(Parse table) {
151         doRows(table.parts.more);
152     }
153 
154     public void doRows(Parse rows) {
155         while (rows != null) {
156             Parse more = rows.more;
157             doRow(rows);
158             rows = more;
159         }
160     }
161 
162     public void doRow(Parse row) {
163         if(debugMode)
164           frame.doRow(row.parts); 
165         doCells(row.parts);
166     }
167 
168     public void doCells(Parse cells) {
169       for (int i=0; cells != null; i++) {
170             try {
171                 doCell(cells, i);
172             } catch (Exception e) {
173                 exception(cells, e);
174             }
175             cells=cells.more;
176         }
177     }
178 
179     public void doCell(Parse cell, int columnNumber) {
180         ignore(cell);
181     }
182 
183 
184     // Annotation ///////////////////////////////
185 
186     public static String green = "#cfffcf";
187     public static String red = "#ffcfcf";
188     public static String gray = "#efefef";
189     public static String yellow = "#ffffcf";
190 
191     public  void right (Parse cell) {
192         cell.addToTag(" bgcolor=\"" + green + "\"");
193         counts.right++;
194     }
195 
196     public void wrong (Parse cell) {
197         cell.addToTag(" bgcolor=\"" + red + "\"");
198 		cell.body = escape(cell.text());
199         counts.wrong++;
200     }
201 
202     public void wrong (Parse cell, String actual) {
203         wrong(cell);
204         cell.addToBody(label("expected") + "<hr>" + escape(actual) + label("actual"));
205     }
206 
207 	public void info (Parse cell, String message) {
208 		cell.addToBody(info(message));
209 	}
210 
211 	public String info (String message) {
212 		return " <font color=\"#808080\">" + escape(message) + "</font>";
213 	}
214 
215     public void ignore (Parse cell) {
216         cell.addToTag(" bgcolor=\"" + gray + "\"");
217         counts.ignores++;
218     }
219 
220 	public void error (Parse cell, String message) {
221 		cell.body = escape(cell.text());
222 		cell.addToBody("<hr><pre>" + escape(message) + "</pre>");
223 		cell.addToTag(" bgcolor=\"" + yellow + "\"");
224 		counts.exceptions++;
225 	}
226 
227     public void exception (Parse cell, Throwable exception) {
228         while(exception.getClass().equals(InvocationTargetException.class)) {
229             exception = ((InvocationTargetException)exception).getTargetException();
230         }
231         final StringWriter buf = new StringWriter();
232         exception.printStackTrace(new PrintWriter(buf));
233         error(cell, buf.toString());
234     }
235 
236     // Utility //////////////////////////////////
237 
238     public String counts() {
239         return counts.toString();
240     }
241 
242     public static String label (String string) {
243         return " <font size=-1 color=\"#c08080\"><i>" + string + "</i></font>";
244     }
245 
246     public static String escape (String string) {
247     	string = string.replaceAll("&", "&amp;");
248     	string = string.replaceAll("<", "&lt;");
249     	string = string.replaceAll("  ", " &nbsp;");
250 		string = string.replaceAll("\r\n", "<br />");
251 		string = string.replaceAll("\r", "<br />");
252 		string = string.replaceAll("\n", "<br />");
253     	return string;
254     }
255 
256     public static String camel (String name) {
257         StringBuffer b = new StringBuffer(name.length());
258         StringTokenizer t = new StringTokenizer(name);
259         if (!t.hasMoreTokens())
260             return name;
261         b.append(t.nextToken());
262         while (t.hasMoreTokens()) {
263             String token = t.nextToken();
264             b.append(token.substring(0, 1).toUpperCase());      // replace spaces with camelCase
265             b.append(token.substring(1));
266         }
267         return b.toString();
268     }
269 
270     public Object parse (String s, Class type) throws Exception {
271         if (type.equals(String.class))              {return s;}
272         if (type.equals(Date.class))                {return DateFormat.getDateInstance().parse(s);}
273         if (type.equals(ScientificDouble.class))    {return ScientificDouble.valueOf(s);}
274         throw new Exception("can't yet parse "+type);
275     }
276 
277     public void check(Parse cell, TypeAdapter a) {
278         String text = cell.text();
279         if (text.equals("")) {
280             try {
281                 info(cell, a.toString(a.get()));
282             } catch (Exception e) {
283                 info(cell, "error");
284             }
285         } else if (a == null) {
286             ignore(cell);
287         } else  if (text.equals("error")) {
288             try {
289                 Object result = a.invoke();
290                 wrong(cell, a.toString(result));
291             } catch (IllegalAccessException e) {
292                 exception (cell, e);
293             } catch (Exception e) {
294                 right(cell);
295             }
296         } else {
297             try {
298                 Object result = a.get();
299                 if (a.equals(a.parse(text), result)) {
300                     right(cell);
301                 } else {
302                     wrong(cell, a.toString(result));
303                 }
304             } catch (Exception e) {
305                 exception(cell, e);
306             }
307         }
308     }
309 
310 	/* Added by Rick, from FitNesse */
311     public String[] getArgs() {
312         return args;
313     }
314 
315 }