001: package com.reeltwo.jumble.fast;
002:
003: import java.io.Serializable;
004: import java.lang.reflect.Constructor;
005: import java.lang.reflect.Method;
006: import java.util.HashMap;
007: import java.util.HashSet;
008: import java.util.Iterator;
009: import java.util.Map;
010: import java.util.Set;
011:
012: import java.lang.reflect.InvocationTargetException;
013:
014: import com.reeltwo.jumble.util.ClassLoaderCloneable;
015:
016: /**
017: * A map from mutation points to failed tests. Used to cache previous test
018: * failures for Jumble.
019: *
020: * @author Tin Pavlinic
021: * @version $Revision: 496 $
022: *
023: */
024: public class FailedTestMap implements Serializable,
025: ClassLoaderCloneable {
026: /**
027: * The map itself: ClassName.MethodName(String) -> (mutationPoint(Integer) ->
028: * testName(String))(Map)
029: */
030: private Map mCache;
031:
032: /**
033: * Constructor. Creates a blank map.
034: */
035: public FailedTestMap() {
036: mCache = new HashMap();
037: }
038:
039: /**
040: * Adds a test name to the cache.
041: *
042: * @param mutatedClass
043: * the name of the mutated class.
044: * @param mutatedMethod
045: * the name of the mutated method.
046: * @param methodRelativeMutationPoint
047: * the number of the mutation point, relative to the mehtod.
048: */
049: public void addFailure(String mutatedClass, String mutatedMethod,
050: int methodRelativeMutationPoint, String testName) {
051: Map mutationToTest;
052:
053: //System.out.println(mutatedMethod);
054:
055: if (mCache.containsKey(mutatedClass + "." + mutatedMethod)) {
056: mutationToTest = (Map) mCache.get(mutatedClass + "."
057: + mutatedMethod);
058: } else {
059: mutationToTest = new HashMap();
060: mCache.put(mutatedClass + "." + mutatedMethod,
061: mutationToTest);
062: }
063:
064: mutationToTest.put(new Integer(methodRelativeMutationPoint),
065: testName);
066: }
067:
068: /**
069: * Gives us the same object loaded in a new class loader.
070: */
071: public Object clone(ClassLoader cl) throws ClassNotFoundException {
072: Class clazz = cl
073: .loadClass("com.reeltwo.jumble.fast.FailedTestMap");
074:
075: try {
076: Constructor constructor = clazz
077: .getConstructor(new Class[0]);
078: Object o = constructor.newInstance(new Object[0]);
079: Method m = clazz.getMethod("addFailure",
080: new Class[] { String.class, String.class,
081: int.class, String.class });
082:
083: Set keys = mCache.keySet();
084: for (Iterator it = keys.iterator(); it.hasNext();) {
085: String curKey = (String) it.next();
086: String className = curKey.substring(0, curKey
087: .indexOf("."));
088: String methodName = curKey.substring(curKey
089: .indexOf(".") + 1);
090: Map map = (Map) mCache.get(curKey);
091:
092: int points = map.size();
093:
094: for (int i = 0; i < points; i++) {
095: String testName = (String) map.get(new Integer(i));
096: m.invoke(o, new Object[] { className, methodName,
097: new Integer(i), testName });
098: }
099: }
100: return o;
101: } catch (InstantiationException e) {
102: e.printStackTrace();
103: throw new ClassNotFoundException(
104: "Error invoking constructor");
105: } catch (InvocationTargetException e) {
106: e.printStackTrace();
107: throw new ClassNotFoundException(
108: "Error invoking constructor");
109: } catch (IllegalAccessException e) {
110: e.printStackTrace();
111: throw new ClassNotFoundException(
112: "Error invoking constructor");
113: } catch (NoSuchMethodException e) {
114: e.printStackTrace();
115: throw new ClassNotFoundException(
116: "Error invoking constructor");
117: }
118: }
119:
120: /**
121: * Returns the name of the test associated with the last failure.
122: *
123: * @param className
124: * mutated class name.
125: * @param methodName
126: * mutated method name.
127: * @param mutationPoint
128: * method relative mutation point.
129: * @return the name of a test, or <code>null</code> if nothing was found.
130: */
131: public String getLastFailure(String className, String methodName,
132: int mutationPoint) {
133: Map map = (Map) mCache.get(className + "." + methodName);
134:
135: if (map == null) {
136: return null;
137: } else {
138: String testName = (String) map.get(new Integer(
139: mutationPoint));
140: return testName;
141: }
142: }
143:
144: /**
145: * Gets a set of all the tests associated with failing on mutating the
146: * specified method.
147: *
148: * @param className
149: * mutated class name.
150: * @param methodName
151: * mutated method name
152: * @return set containing the names of the tests which fail on the given
153: * method.
154: */
155: public Set getFailedTests(String className, String methodName) {
156: // System.out.println(mCache);
157: Map map = (Map) mCache.get(className + "." + methodName);
158: if (map != null) {
159: return new HashSet(map.values());
160: } else {
161: return new HashSet();
162: }
163: }
164:
165: public String toString() {
166: return mCache.toString();
167: }
168: }
|