001: package csdl.jblanket.modifier;
002:
003: import java.io.File;
004:
005: import junit.framework.TestCase;
006:
007: import org.apache.bcel.Constants;
008: import org.apache.bcel.classfile.ClassParser;
009: import org.apache.bcel.classfile.JavaClass;
010: import org.apache.bcel.classfile.LineNumberTable;
011: import org.apache.bcel.classfile.Method;
012: import org.apache.bcel.generic.ClassGen;
013: import org.apache.bcel.generic.ConstantPoolGen;
014: import org.apache.bcel.generic.MethodGen;
015:
016: import csdl.jblanket.methodset.MethodInfo;
017: import csdl.jblanket.methodset.MethodSet;
018: import csdl.jblanket.methodset.MethodSetManager;
019: import csdl.jblanket.util.MethodCategories;
020:
021: /**
022: * Tests the MethodModifier class.
023: *
024: * @author Joy M. Agustin
025: * @version $Id: TestMethodModifier.java,v 1.6 2005/03/08 19:34:06 johnson Exp $
026: */
027: public class TestMethodModifier extends TestCase {
028:
029: /** MethodCounter object */
030: private MethodCounter counter;
031:
032: /** Stack.class */
033: private JavaClass clazz;
034:
035: /** Array of methods in Stack.class */
036: private Method[] methods;
037:
038: /** Directory separator */
039: private static final String SLASH = File.separator;
040:
041: /**
042: * Constructor required by JUnit.
043: *
044: * @param name
045: * the name of this test class.
046: */
047: public TestMethodModifier(String name) {
048: super (name);
049: }
050:
051: /**
052: * Sets up the instance variables for each test case.
053: *
054: * @throws Exception
055: * when unable to complete a setup.
056: */
057: public void setUp() throws Exception {
058:
059: String testDir = System.getProperty("jblanket.data.dir");
060: File dir = new File(testDir, "unjar");
061: File classDir = new File(dir, "edu" + SLASH + "hawaii" + SLASH
062: + "stack");
063: File inFile = new File(classDir, "Debug.class");
064: System.setProperty("jblanket.dir", testDir + SLASH + "xml");
065:
066: this .counter = new MethodCounter();
067:
068: // retrieve class byte code -- throws IOException
069: this .clazz = (new ClassParser(inFile.getAbsolutePath()))
070: .parse();
071: this .methods = clazz.getMethods();
072: }
073:
074: /**
075: * Tests the modifyMethods, hasLineNumbers, isConstructor methods.
076: */
077: public void testModifyMethods() {
078:
079: String userDir = System.getProperty("jblanket.testdir") + SLASH
080: + "testmethodmodifier";
081: System.setProperty("jblanket.dir", userDir);
082:
083: ConstantPoolGen pool = new ConstantPoolGen(clazz
084: .getConstantPool());
085: MethodCategories categories = MethodCategories.getInstance();
086: MethodSetManager manager = MethodSetManager.getInstance();
087: MethodSet constructorSet = manager.getMethodSet(categories
088: .getFileName("constructorFile"));
089: MethodSet oneLineSet = manager.getMethodSet(categories
090: .getFileName("oneLineFile"));
091:
092: int oldConstructorSetSize = constructorSet.size();
093: int oldOneLineSetSize = oneLineSet.size();
094:
095: // test the constructor '<init>'
096: MethodGen method = new MethodGen(methods[0], clazz
097: .getClassName(), pool);
098: MethodModifier modifier = new MethodModifier(false,
099: "Test*.class", true, false, true, method);
100: Method processedMethod = modifier.processMethod(pool, true);
101: assertEquals("Checking if has line numbers", true, modifier
102: .hasLineNumbers());
103: assertEquals("Checking if one-line method", false, modifier
104: .isOneLine());
105: assertEquals("Checking if constructor", true, modifier
106: .isConstructor());
107: assertEquals("Checking size of constructor MethodSet",
108: ++oldConstructorSetSize, constructorSet.size());
109: assertEquals("Checking size of one-line MethodSet",
110: oldOneLineSetSize, oneLineSet.size());
111:
112: // test the 'getRelease' method
113: method = new MethodGen(methods[1], clazz.getClassName(), pool);
114: modifier = new MethodModifier(false, "Test*.class", true,
115: false, true, method);
116: processedMethod = modifier.processMethod(pool, true);
117: assertEquals("Checking if has line numbers", true, modifier
118: .hasLineNumbers());
119: assertEquals("Checking if one-line method", true, modifier
120: .isOneLine());
121: assertEquals("Checking if constructor", false, modifier
122: .isConstructor());
123: assertEquals("Checking size of constructor MethodSet",
124: oldConstructorSetSize, constructorSet.size());
125: assertEquals("Checking size of one-line MethodSet",
126: ++oldOneLineSetSize, oneLineSet.size());
127: }
128:
129: /**
130: * Tests the modifyMethods, hasLineNumbers, isConstructor methods.
131: */
132: public void testUntestableConstructorMethods() {
133:
134: String userDir = System.getProperty("jblanket.testdir") + SLASH
135: + "testmethodmodifier";
136: System.setProperty("jblanket.dir", userDir);
137:
138: ConstantPoolGen pool = new ConstantPoolGen(clazz
139: .getConstantPool());
140: MethodCategories categories = MethodCategories.getInstance();
141: MethodSetManager manager = MethodSetManager.getInstance();
142: MethodSet constructorSet = manager.getMethodSet(categories
143: .getFileName("constructorFile"));
144: MethodSet untestableSet = manager.getMethodSet(categories
145: .getFileName("untestableFile"));
146: MethodSet oneLineSet = manager.getMethodSet(categories
147: .getFileName("oneLineFile"));
148:
149: int oldConstructorSetSize = constructorSet.size();
150: int oldUntestableSetSize = untestableSet.size();
151: int oldOneLineSetSize = oneLineSet.size();
152:
153: // test the constructor '<init>'
154: MethodGen method = new MethodGen(methods[0], clazz
155: .getClassName(), pool);
156: MethodModifier modifier = new MethodModifier(false,
157: "Test*.class", true, false, true, method);
158: Method processedMethod = modifier.processMethod(pool, true);
159: assertEquals("Checking if has line numbers", true, modifier
160: .hasLineNumbers());
161: assertEquals("Checking if one-line method", false, modifier
162: .isOneLine());
163: assertEquals("Checking if constructor", true, modifier
164: .isConstructor());
165: assertEquals("Checking size of constructor MethodSet",
166: oldConstructorSetSize, constructorSet.size());
167: assertEquals("Checking size of untestable MethodSet",
168: oldUntestableSetSize + 1, untestableSet.size());
169: assertEquals("Checking size of one-line MethodSet",
170: oldOneLineSetSize, oneLineSet.size());
171:
172: // test the 'getRelease' method
173: method = new MethodGen(methods[1], clazz.getClassName(), pool);
174: modifier = new MethodModifier(false, "Test*.class", true,
175: false, true, method);
176: processedMethod = modifier.processMethod(pool, true);
177: assertEquals("Checking if has line numbers", true, modifier
178: .hasLineNumbers());
179: assertEquals("Checking if one-line method", true, modifier
180: .isOneLine());
181: assertEquals("Checking if constructor", false, modifier
182: .isConstructor());
183: assertEquals("Checking size of constructor MethodSet",
184: oldConstructorSetSize, constructorSet.size());
185: assertEquals("Checking size of one-line MethodSet",
186: ++oldOneLineSetSize, oneLineSet.size());
187: }
188:
189: /**
190: * Tests the excludeMethod method.
191: */
192: public void testExcludeMethod() {
193:
194: MethodSet excludeSet = new MethodSet();
195: ConstantPoolGen pool = new ConstantPoolGen(clazz
196: .getConstantPool());
197:
198: // get the constructor '<init>'
199: MethodGen method = new MethodGen(methods[0], clazz
200: .getClassName(), pool);
201: MethodModifier modifier = new MethodModifier(false,
202: "Test*.class", true, false, true, method);
203: modifier.excludeMethod(excludeSet);
204: assertEquals("Checking size of exclude MethodSet", 1,
205: excludeSet.size());
206: MethodInfo methodInfo = (MethodInfo) excludeSet.iterator()
207: .next();
208: assertEquals("Checking the name of constructor",
209: "edu.hawaii.stack.Debug", methodInfo.getClassName());
210: }
211:
212: /**
213: * Test methods created by a process like AspectJ or BCEL that don't have
214: * line numbers. See JBL-5.
215: */
216: public void testGeneratedMethods() {
217: // Remove default constructor from regular test class
218: ClassGen classGen = new ClassGen(clazz);
219: classGen.removeMethod(methods[0]);
220: classGen.addEmptyConstructor(Constants.ACC_PUBLIC);
221:
222: // Use our modified test class to test against
223: clazz = classGen.getJavaClass();
224: methods = clazz.getMethods();
225: for (int i = 0; i < methods.length; i++) {
226: Method method = methods[i];
227: System.out.println(method.getName() + ": "
228: + getLineNumberCount(method));
229: }
230:
231: String dataDir = System.getProperty("jblanket.data.dir")
232: + SLASH + "xml";
233: assertNotNull("Checking for presence of jblanket.data.dir.",
234: dataDir);
235: System.setProperty("jblanket.dir", dataDir);
236:
237: ConstantPoolGen pool = new ConstantPoolGen(clazz
238: .getConstantPool());
239: MethodCategories categories = MethodCategories.getInstance();
240: MethodSetManager manager = MethodSetManager.getInstance();
241: MethodSet constructorSet = manager.getMethodSet(categories
242: .getFileName("constructorFile"));
243: MethodSet oneLineSet = manager.getMethodSet(categories
244: .getFileName("oneLineFile"));
245:
246: int oldConstructorSetSize = constructorSet.size();
247: int oldOneLineSetSize = oneLineSet.size();
248:
249: // test the constructor '<init>'
250: MethodGen constructor = new MethodGen(
251: methods[methods.length - 1], clazz.getClassName(), pool);
252: MethodModifier modifier = new MethodModifier(false,
253: "Test*.class", true, true, true, constructor);
254: Method processedMethod = modifier.processMethod(pool, true);
255: assertEquals("Checking if has line numbers", false, modifier
256: .hasLineNumbers());
257: assertEquals("Checking if one-line method", false, modifier
258: .isOneLine());
259: assertEquals("Checking if constructor", true, modifier
260: .isConstructor());
261: assertEquals("Checking size of constructor MethodSet",
262: oldConstructorSetSize, constructorSet.size());
263: assertEquals("Checking size of one-line MethodSet",
264: oldOneLineSetSize, oneLineSet.size());
265: }
266:
267: /**
268: * @param method
269: * @return
270: */
271: private int getLineNumberCount(Method method) {
272: LineNumberTable lineNumberTable = method.getLineNumberTable();
273: return lineNumberTable == null ? 0 : lineNumberTable
274: .getLength();
275: }
276: }
|