001: /* QuiltTest.java */
002:
003: package org.quilt.framework;
004:
005: import java.io.File;
006: import java.util.Enumeration;
007: import java.util.Hashtable;
008: import java.util.Properties;
009: import java.util.Vector;
010:
011: import org.apache.tools.ant.Project; //import org.apache.tools.ant.taskdefs.optional.junit.*;
012:
013: import org.quilt.reports.*;
014:
015: /**
016: * Parameters for controlling an individual task. These are and
017: * must be compatible with names used in Ant build.xml build control
018: * files. Most are set by methods whose name is derived from
019: * the variable name -- for example <b>fork</b> is set by
020: * <b>setFork(b)</b>.
021: */
022: public class QuiltTest implements Cloneable {
023:
024: /** Class name of the test */
025: private String name = null;
026:
027: // MAINTAINERS please keep the variable names and their get/set
028: // methods in alphabetical order
029:
030: /** If true, running Quilt coverage checks. */
031: private boolean checkCoverage = false;
032:
033: /**
034: * Classes not be to instrumented, a comma-separated list of class
035: * names. Wildcards are OK. com.xyz.* means all classes whose
036: * name begins with com.xyz, but does not include com.xyz itself.
037: *
038: */
039: private String checkExcludes;
040:
041: /**
042: * Classes to instrument if checking coverage. Comma-separated,
043: * wildcards OK.
044: */
045: private String checkIncludes;
046:
047: /** Set this property to True if an error occurs.*/
048: private String errorProperty;
049:
050: /** Name of property to set to True if a failure or error occurs. */
051: private String failureProperty;
052:
053: /** Filter Quilt and JUnit error/failure messages from output. */
054: private boolean filtertrace = true;
055:
056: /** Run the test in a separate JVM. */
057: private boolean fork = false;
058:
059: /** Names of formatters to be used. */
060: private Vector formatters = new Vector();
061:
062: /** Halt the test if an unexpected error occurs. */
063: private boolean haltOnError = false;
064:
065: /** Halt the test if a failure (expected) or error occurs. */
066: private boolean haltOnFailure = false;
067:
068: /** Run the test only if this property is True. */
069: private String ifProperty = null;
070:
071: /** Don't run the test, just report back the parameters. */
072: private boolean mockTestRun = false;
073:
074: /** Where to write the results */
075: private String outfile = null;
076:
077: /** Copy of Ant properties */
078: private Properties props = new Properties();
079:
080: /**
081: * Ant documentation seems contradictory on this, but it MUST
082: * be a QuiltTest field. Used in BaseTestRunner. XXX
083: */
084: private boolean showOutput = false;
085:
086: /** Report destination directory. */
087: private File todir = null;
088:
089: /** Run the test unless this property is True. */
090: private String unlessProperty = null;
091:
092: // CONSTRUCTORS /////////////////////////////////////////////////
093: /** No-arg constructor used by clone() */
094: public QuiltTest() {
095: }
096:
097: /**
098: * Single-arg constructor.
099: *
100: * @param name Full class name of test to be run.
101: */
102: public QuiltTest(String name) {
103: this .name = name;
104: }
105:
106: // NON-STANDARD VARIABLES AND GET/SET METHODS ///////////////////
107: /**
108: * DON'T BELONG HERE - TEST RESULTS. These are not accessible
109: * from Ant
110: */
111: private long errors = (long) 0;
112: private long failures = (long) 0;
113: private long runs = (long) 0;
114: private long runTime = (long) 0;
115:
116: public void setCounts(long runs, long failures, long errors) {
117: this .errors = errors;
118: this .failures = failures;
119: this .runs = runs;
120: }
121:
122: public long errorCount() {
123: return errors;
124: }
125:
126: public long failureCount() {
127: return failures;
128: }
129:
130: public long runCount() {
131: return runs;
132: }
133:
134: // END ERRATIC NAMES ////////////////////////////////////////////
135:
136: /** @return A reference to the test's Properties */
137: public Properties getProperties() {
138: return props;
139: }
140:
141: /**
142: * Replace the test's Properties. This is quite different from
143: * the method in JUnitTask, which seems to contain errors.
144: *
145: * @param val Hashtable containing new values.
146: */
147:
148: public void setProperties(Hashtable val) {
149: Enumeration e = val.keys();
150: props.clear();
151: while (e.hasMoreElements()) {
152: Object key = e.nextElement();
153: props.put(key, val.get(key));
154: }
155: }
156:
157: public long getRunTime() {
158: return runTime;
159: }
160:
161: public void setRunTime(long val) {
162: runTime = val;
163: }
164:
165: // //////////////////////////////////////////////////////////////
166: // GET RID OF THIS METHOD ///////////////////////////////////////
167: // //////////////////////////////////////////////////////////////
168:
169: /** Add this test's formatters to a vector. A convenience method
170: * with a mildly confusing name. Inherited from JUnitTask. */
171: public void addFormattersTo(Vector v) {
172: for (int j = 0; j < formatters.size(); j++) {
173: v.addElement(formatters.elementAt(j));
174: }
175: }
176:
177: // ADD/GET/SET METHODS /////////////////////////////////
178: public boolean getCheckCoverage() {
179: return checkCoverage;
180: }
181:
182: public void setCheckCoverage(boolean b) {
183: checkCoverage = b;
184: }
185:
186: public String getCheckExcludes() {
187: return checkExcludes;
188: }
189:
190: public String[] getCheckExcludesArray() {
191: String[] val = null;
192: if (checkExcludes != null) {
193: val = checkExcludes.split(",");
194: }
195: return val;
196: }
197:
198: public void setCheckExcludes(String val) {
199: checkExcludes = val;
200: }
201:
202: public String getCheckIncludes() {
203: return checkIncludes;
204: }
205:
206: public String[] getCheckIncludesArray() {
207: String[] val = null;
208: if (checkIncludes != null) {
209: val = checkIncludes.split(",");
210: }
211: return val;
212: }
213:
214: public void setCheckIncludes(String val) {
215: checkIncludes = val;
216: }
217:
218: public String getErrorProperty() {
219: return errorProperty;
220: }
221:
222: public void setErrorProperty(String eP) {
223: errorProperty = eP;
224: }
225:
226: public String getFailureProperty() {
227: return failureProperty;
228: }
229:
230: public void setFailureProperty(String fP) {
231: failureProperty = fP;
232: }
233:
234: public boolean getFiltertrace() {
235: return filtertrace;
236: }
237:
238: public void setFiltertrace(boolean b) {
239: filtertrace = b;
240: }
241:
242: public boolean getFork() {
243: return fork;
244: }
245:
246: public void setFork(boolean b) {
247: fork = b;
248: }
249:
250: public void addFormatter(FmtSelector elem) {
251: formatters.addElement(elem);
252: }
253:
254: public Vector getFormatters() {
255: return formatters;
256: }
257:
258: public boolean getHaltOnError() {
259: return haltOnError;
260: }
261:
262: public void setHaltOnError(boolean b) {
263: haltOnError = b;
264: }
265:
266: public boolean getHaltOnFailure() {
267: return haltOnFailure;
268: }
269:
270: public void setHaltOnFailure(boolean b) {
271: haltOnFailure = b;
272: }
273:
274: // non-standard name required for compatibility
275: public String getIfProperty() {
276: return ifProperty;
277: }
278:
279: public void setIf(String name) {
280: ifProperty = name;
281: }
282:
283: public boolean getMockTestRun() {
284: return mockTestRun;
285: }
286:
287: public void setMockTestRun(boolean b) {
288: mockTestRun = b;
289: }
290:
291: public String getName() {
292: return name;
293: }
294:
295: public void setName(String val) {
296: name = val;
297: }
298:
299: public String getOutfile() {
300: return outfile;
301: }
302:
303: public void setOutfile(String val) {
304: outfile = val;
305: }
306:
307: public boolean getShowOutput() {
308: return showOutput;
309: }
310:
311: public void setShowOutput(boolean b) {
312: showOutput = b;
313: }
314:
315: public String getTodir() {
316: if (todir != null) {
317: return todir.getAbsolutePath();
318: }
319: return null;
320: }
321:
322: public void setTodir(File dir) {
323: this .todir = dir;
324: }
325:
326: // non-standard name required for compatibility
327: public String getUnlessProperty() {
328: return unlessProperty;
329: }
330:
331: public void setUnless(String name) {
332: unlessProperty = name;
333: }
334:
335: // IMPLEMENT Cloneable //////////////////////////////////////////
336: /**
337: * Clones, resetting the error/failure/run counts and runTime to zero.
338: *
339: * @return An Object, a copy of this QuiltTest.
340: */
341: public Object clone() {
342: QuiltTest t = new QuiltTest();
343: t.name = name;
344:
345: // counts and runTime are not copied
346:
347: t.checkCoverage = checkCoverage;
348: t.checkExcludes = checkExcludes;
349: t.checkIncludes = checkIncludes;
350: t.errorProperty = errorProperty;
351: t.failureProperty = failureProperty;
352: t.filtertrace = filtertrace;
353: t.formatters = (Vector) formatters.clone();
354: t.fork = fork;
355: t.haltOnError = haltOnError;
356: t.haltOnFailure = haltOnFailure;
357: t.ifProperty = ifProperty;
358: t.mockTestRun = mockTestRun;
359: t.outfile = outfile;
360: t.showOutput = showOutput;
361: t.todir = todir;
362: t.unlessProperty = unlessProperty;
363:
364: // real Properties are harder to clone
365: Properties props = getProperties();
366: if (props != null) {
367: t.setProperties((Properties) props.clone());
368: }
369: return t;
370: }
371:
372: // TOSTRING () //////////////////////////////////////////////////
373: public String toString() {
374: String fmtStr = "";
375: for (int i = 0; i < formatters.size(); i++)
376: fmtStr += formatters.elementAt(i) + " ";
377:
378: String pStr;
379: if (props != null) {
380: pStr = "";
381: Enumeration e = props.keys();
382: while (e.hasMoreElements()) {
383: String name = (String) e.nextElement();
384: String value = (String) props.getProperty(name);
385: pStr += "\n (" + name + " --> " + value + ")";
386: }
387: } else {
388: pStr = "<none>";
389: }
390: String s = " test name: " + name
391:
392: + "\n checkCoverage: " + checkCoverage
393: + "\n checkExcludes: "
394: + (checkExcludes == null ? "" : checkExcludes)
395: + "\n checkIncludes: "
396: + (checkIncludes == null ? "" : checkIncludes)
397: + "\n errorProperty: " + errorProperty
398: + "\n failureProperty: " + failureProperty
399: + "\n filtertrace: " + filtertrace
400: + "\n fork: " + fork
401: + "\n formatters: " + fmtStr
402: + "\n haltOnError: " + haltOnError
403: + "\n haltOnFailure: " + haltOnFailure
404: + "\n ifProperty: " + ifProperty
405: + "\n mockTestRun: " + mockTestRun
406: + "\n outfile: " + outfile
407: + "\n showOutput: " + showOutput
408: + "\n todir: " + todir
409: + "\n unlessProperty: "
410: + unlessProperty
411:
412: // counts - not cloned but part of toString()
413: + "\n errors: " + errors
414: + "\n failures: " + failures
415: + "\n runs: " + runs
416:
417: + "\n other properties:" + pStr;
418: return s;
419: }
420:
421: // CONVENIENCE METHOD ///////////////////////////////////////////
422: /**
423: * Run this test if project properties permit.
424: *
425: * @param p The project that the QuiltTask is part of.
426: * @return True if this test should be run, false otherwise.
427: */
428: public boolean runMe(Project p) {
429: if (ifProperty != null) {
430: if (p.getProperty(ifProperty) == null)
431: return false;
432: }
433: if (unlessProperty != null) {
434: if (p.getProperty(ifProperty) != null)
435: return false;
436: }
437: return true;
438: }
439: }
|