KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hudson > tasks > junit > CaseResult


1 package hudson.tasks.junit;
2
3 import hudson.model.AbstractBuild;
4 import org.dom4j.Element;
5
6 import java.util.Comparator JavaDoc;
7
8 /**
9  * One test result.
10  *
11  * @author Kohsuke Kawaguchi
12  */

13 public final class CaseResult extends TestObject implements Comparable JavaDoc<CaseResult> {
14     private final String JavaDoc className;
15     private final String JavaDoc testName;
16     private final String JavaDoc errorStackTrace;
17     private transient SuiteResult parent;
18
19     private transient ClassResult classResult;
20
21     /**
22      * This test has been failing since this build number (not id.)
23      *
24      * If {@link #isPassed() passing}, this field is left unused to 0.
25      */

26     private /*final*/ int failedSince;
27
28     CaseResult(SuiteResult parent, Element testCase) {
29         String JavaDoc cn = testCase.attributeValue("classname");
30         if(cn==null)
31             // Maven seems to skip classname, and that shows up in testSuite/@name
32
cn = parent.getName();
33         className = cn.replace('/','_'); // avoid unsafe chars
34
testName = testCase.attributeValue("name").replace('/','_');
35         errorStackTrace = getError(testCase);
36     }
37
38     private String JavaDoc getError(Element testCase) {
39         String JavaDoc msg = testCase.elementText("error");
40         if(msg!=null)
41             return msg;
42         return testCase.elementText("failure");
43     }
44
45     public String JavaDoc getDisplayName() {
46         return testName;
47     }
48
49     /**
50      * Gets the name of the test, which is returned from {@code TestCase.getName()}
51      *
52      * <p>
53      * Note that this may contain any URL-unfriendly character.
54      */

55     public String JavaDoc getName() {
56         return testName;
57     }
58
59     /**
60      * Gets the version of {@link #getName()} that's URL-safe.
61      */

62     public String JavaDoc getSafeName() {
63         StringBuffer JavaDoc buf = new StringBuffer JavaDoc(testName);
64         for( int i=0; i<buf.length(); i++ ) {
65             char ch = buf.charAt(i);
66             if(!Character.isJavaIdentifierPart(ch))
67                 buf.setCharAt(i,'_');
68         }
69         return buf.toString();
70     }
71
72     /**
73      * Gets the class name of a test class.
74      */

75     public String JavaDoc getClassName() {
76         return className;
77     }
78
79     /**
80      * Gets the simple (not qualified) class name.
81      */

82     public String JavaDoc getSimpleName() {
83         int idx = className.lastIndexOf('.');
84         return className.substring(idx+1);
85     }
86
87     /**
88      * Gets the package name of a test case
89      */

90     public String JavaDoc getPackageName() {
91         int idx = className.lastIndexOf('.');
92         if(idx<0) return "(root)";
93         else return className.substring(0,idx);
94     }
95
96     public String JavaDoc getFullName() {
97         return className+'.'+getName();
98     }
99
100     /**
101      * If this test failed, then return the build number
102      * when this test started failing.
103      */

104     public int getFailedSince() {
105         return failedSince;
106     }
107
108     /**
109      * Gets the number of consecutive builds (including this)
110      * that this test case has been failing.
111      */

112     public int getAge() {
113         if(isPassed())
114             return 0;
115         else
116             return getOwner().getNumber()-failedSince+1;
117     }
118
119     @Override JavaDoc
120     public CaseResult getPreviousResult() {
121         SuiteResult pr = parent.getPreviousResult();
122         if(pr==null) return null;
123         return pr.getCase(getName());
124     }
125
126     /**
127      * If there was an error or a failure, this is the stack trace, or otherwise null.
128      */

129     public String JavaDoc getErrorStackTrace() {
130         return errorStackTrace;
131     }
132
133     public boolean isPassed() {
134         return errorStackTrace==null;
135     }
136
137     public SuiteResult getParent() {
138         return parent;
139     }
140
141     public AbstractBuild<?,?> getOwner() {
142         return parent.getParent().getOwner();
143     }
144
145     /**
146      * Gets the relative path to this test case from the given object.
147      */

148     public String JavaDoc getRelativePathFrom(TestObject it) {
149         if(it==this)
150             return ".";
151         
152         // package, then class
153
StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
154         buf.append(getSafeName());
155         if(it!=classResult) {
156             buf.insert(0,'/');
157             buf.insert(0,classResult.getName());
158
159             PackageResult pkg = classResult.getParent();
160             if(it!=pkg) {
161                 buf.insert(0,'/');
162                 buf.insert(0,pkg.getName());
163             }
164         }
165
166         return buf.toString();
167     }
168
169     public void freeze(SuiteResult parent) {
170         this.parent = parent;
171         // some old test data doesn't have failedSince value set, so for those compute them.
172
if(!isPassed() && failedSince==0) {
173             CaseResult prev = getPreviousResult();
174             if(prev!=null && !prev.isPassed())
175                 this.failedSince = prev.failedSince;
176             else
177                 this.failedSince = getOwner().getNumber();
178         }
179     }
180
181     public int compareTo(CaseResult that) {
182         return this.getFullName().compareTo(that.getFullName());
183     }
184
185     public Status getStatus() {
186         CaseResult pr = getPreviousResult();
187         if(pr==null) {
188             return isPassed() ? Status.PASSED : Status.FAILED;
189         }
190
191         if(pr.isPassed()) {
192             return isPassed() ? Status.PASSED : Status.REGRESSION;
193         } else {
194             return isPassed() ? Status.FIXED : Status.FAILED;
195         }
196     }
197
198     /*package*/ void setClass(ClassResult classResult) {
199         this.classResult = classResult;
200     }
201
202     /**
203      * Constants that represent the status of this test.
204      */

205     public enum Status {
206         /**
207          * This test runs OK, just like its previous run.
208          */

209         PASSED("result-passed","Passed",true),
210         /**
211          * This test failed, just like its previous run.
212          */

213         FAILED("result-failed","Failed",false),
214         /**
215          * This test has been failing, but now it runs OK.
216          */

217         FIXED("result-fixed","Fixed",true),
218         /**
219          * This test has been running OK, but now it failed.
220          */

221         REGRESSION("result-regression","Regression",false);
222
223         private final String JavaDoc cssClass;
224         private final String JavaDoc message;
225         public final boolean isOK;
226
227         Status(String JavaDoc cssClass, String JavaDoc message, boolean OK) {
228            this.cssClass = cssClass;
229            this.message = message;
230            isOK = OK;
231        }
232
233         public String JavaDoc getCssClass() {
234             return cssClass;
235         }
236
237         public String JavaDoc getMessage() {
238             return message;
239         }
240
241         public boolean isRegression() {
242             return this==REGRESSION;
243         }
244     }
245
246     /**
247      * For sorting errors by age.
248      */

249     /*package*/ static final Comparator JavaDoc<CaseResult> BY_AGE = new Comparator JavaDoc<CaseResult>() {
250         public int compare(CaseResult lhs, CaseResult rhs) {
251             return lhs.getAge()-rhs.getAge();
252         }
253     };
254 }
255
Popular Tags