KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > edu > umd > cs > findbugs > detect > InvalidJUnitTest


1 /*
2  * FindBugs - Find bugs in Java programs
3  * Copyright (C) 2004,2005 Dave Brosius <dbrosius@users.sourceforge.net>
4  * Copyright (C) 2005 William Pugh
5  * Copyright (C) 2004,2005 University of Maryland
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package edu.umd.cs.findbugs.detect;
23
24
25 import edu.umd.cs.findbugs.*;
26 import edu.umd.cs.findbugs.ba.ClassContext;
27 import org.apache.bcel.Repository;
28 import org.apache.bcel.classfile.*;
29
30 public class InvalidJUnitTest extends BytecodeScanningDetector {
31
32     private static final int SEEN_NOTHING = 0;
33
34     private static final int SEEN_ALOAD_0 = 1;
35
36     private BugReporter bugReporter;
37     private boolean checkedTestCaseClass;
38     private boolean haveTestCaseClass;
39
40     private int state;
41
42     public InvalidJUnitTest(BugReporter bugReporter) {
43         this.bugReporter = bugReporter;
44     }
45
46
47
48     boolean directChildOfTestCase;
49
50     @Override JavaDoc
51          public void visitClassContext(ClassContext classContext) {
52         if (!enabled())
53             return;
54         
55         JavaClass jClass = classContext.getJavaClass();
56
57         try {
58             if (!Repository.instanceOf(jClass, "junit.framework.TestCase"))
59                 return;
60             
61             if ((jClass.getAccessFlags() & ACC_ABSTRACT) == 0) {
62                 Method[] methods = jClass.getMethods();
63                 boolean foundTest = false;
64                 for (Method m : methods) {
65                     if (m.getName().startsWith("test")) {
66                         foundTest = true;
67                         break;
68                     }
69                 }
70                 if (!foundTest && !hasSuite(methods)) {
71                     bugReporter.reportBug( new BugInstance( this, "IJU_NO_TESTS", LOW_PRIORITY)
72                             .addClass(jClass));
73                 }
74             }
75
76             JavaClass superClass = jClass.getSuperClass();
77             directChildOfTestCase = superClass.getClassName().equals(
78                     "junit.framework.TestCase");
79             jClass.accept(this);
80         } catch (ClassNotFoundException JavaDoc cnfe) {
81             bugReporter.reportMissingClass(cnfe);
82         }
83
84     }
85
86     /** is there a JUnit3TestSuite */
87     private boolean hasSuite(Method[] methods) {
88         for (Method m : methods) {
89             if (m.getName().equals("suite")
90                 && m.isPublic()
91                 && m.isStatic()
92               //&& m.getReturnType().equals(junit.framework.Test.class)
93
//&& m.getArgumentTypes().length == 0
94
&& m.getSignature().equals("()Ljunit/framework/Test;"))
95               return true;
96         }
97         return false;
98     }
99
100     /**
101      * Check whether or not this detector should be enabled.
102      * The detector is disabled if the TestCase class cannot be found
103      * (meaning we don't have junit.jar on the aux classpath).
104      *
105      * @return true if it should be enabled, false if not
106      */

107     private boolean enabled() {
108         if (!checkedTestCaseClass) {
109             checkedTestCaseClass = true;
110             try {
111                 Repository.lookupClass("junit.framework.TestCase");
112                 haveTestCaseClass = true;
113             } catch (ClassNotFoundException JavaDoc e) {
114                 // No TestCase class, so don't bother running
115
// the detector.
116
}
117         }
118         
119         return haveTestCaseClass;
120     }
121
122     @Override JavaDoc
123          public void visit(Method obj) {
124         if (getMethodName().equals("suite") && !obj.isStatic())
125             bugReporter.reportBug(new BugInstance(this, "IJU_SUITE_NOT_STATIC",
126                     NORMAL_PRIORITY).addClassAndMethod(this));
127
128     }
129
130     private boolean sawSuperCall;
131
132     @Override JavaDoc
133          public void visit(Code obj) {
134         if (!directChildOfTestCase
135                 && (getMethodName().equals("setUp") || getMethodName().equals(
136                         "tearDown"))
137                 && !getMethod().isPrivate()) {
138             sawSuperCall = false;
139             super.visit(obj);
140             if (sawSuperCall)
141                 return;
142             JavaClass we = Lookup.findSuperImplementor(getThisClass(),
143                     getMethodName(), "()V", bugReporter);
144             if (we != null && !we.getClassName().equals("junit.framework.TestCase")) {
145                 // OK, got a bug
146
bugReporter.reportBug(new BugInstance(this, getMethodName()
147                         .equals("setUp") ? "IJU_SETUP_NO_SUPER"
148                         : "IJU_TEARDOWN_NO_SUPER", NORMAL_PRIORITY)
149                         .addClassAndMethod(this));
150             }
151         }
152     }
153
154     @Override JavaDoc
155          public void sawOpcode(int seen) {
156         switch (state) {
157         case SEEN_NOTHING:
158             if (seen == ALOAD_0)
159                 state = SEEN_ALOAD_0;
160             break;
161
162         case SEEN_ALOAD_0:
163             if ((seen == INVOKESPECIAL)
164                     && (getNameConstantOperand().equals(getMethodName()))
165                     && (getMethodSig().equals("()V")))
166                 sawSuperCall = true;
167             state = SEEN_NOTHING;
168             break;
169         default:
170             state = SEEN_NOTHING;
171         }
172     }
173 }
174
175 // vim:ts=4
176
Popular Tags