diff --git a/src/main/java/nl/jssl/autounit/Configuration.java b/src/main/java/nl/jssl/autounit/Configuration.java index 3fc4a9e..c9c523d 100644 --- a/src/main/java/nl/jssl/autounit/Configuration.java +++ b/src/main/java/nl/jssl/autounit/Configuration.java @@ -4,17 +4,20 @@ import javassist.ClassPool; import javassist.NotFoundException; /** - * TODO make configurable * */ public class Configuration { public static ClassPool getClassPool() { ClassPool classPool = new ClassPool(); try { - classPool.appendClassPath("bin"); + classPool.appendClassPath(getClasspathSettingOrEclipseDefault()); } catch (NotFoundException e) { throw new RuntimeException(e); } return classPool; } + + private static String getClasspathSettingOrEclipseDefault() { + return System.getProperty("autounit.cp", "bin"); + } } diff --git a/src/main/java/nl/jssl/autounit/JUnitTestCreator.java b/src/main/java/nl/jssl/autounit/JUnitTestCreator.java index aab7a7c..03da83d 100644 --- a/src/main/java/nl/jssl/autounit/JUnitTestCreator.java +++ b/src/main/java/nl/jssl/autounit/JUnitTestCreator.java @@ -6,49 +6,50 @@ import java.io.FileOutputStream; import java.io.PrintStream; import nl.jssl.autounit.classanalyser.ClassAnalyser; +import nl.jssl.autounit.classanalyser.ClassResults; import nl.jssl.autounit.results.JUnitSourceWriter; /** * Creates a Junit source file * */ -public class JUnitTestCreator { +public class JUnitTestCreator { private static final String SOURCEDIRECTORY = "src/outcome/java/"; + private final Class classUnderTest; + private final File packageDirectory; - public void assembleJUnitTest(Class type) { + public JUnitTestCreator(Class type) { + this.classUnderTest = type; + packageDirectory = createPackageDirectory(); + } + + public void create() { try { - tryAssembleJUnitTest(type); + writeSourceFile(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } } - private void tryAssembleJUnitTest(Class type) throws FileNotFoundException { - writeSourceFile(createPackageDirectory(type), type); + private void writeSourceFile() throws FileNotFoundException { + ClassResults results = new ClassAnalyser<>(classUnderTest).analyseAndGetResults(); + getSourceWriter(packageDirectory).write(results); } - private void writeSourceFile(File packageDirectory, Class classUnderTest) throws FileNotFoundException { - resultsWriter(packageDirectory, classUnderTest).write(new ClassAnalyser(classUnderTest).analyse()); + private JUnitSourceWriter getSourceWriter(File packageDirectory) throws FileNotFoundException { + return new JUnitSourceWriter(new PrintStream(new FileOutputStream(getSourceFile()))); } - private JUnitSourceWriter resultsWriter(File packageDirectory, Class type) throws FileNotFoundException { - return new JUnitSourceWriter( - new PrintStream(new FileOutputStream(toSourceFile(packageDirectory, type)))); - } - - private File createPackageDirectory(Class type) { - File packageDirectory = toPackageDirectory(type); + private File createPackageDirectory() { + File packageDirectory = new File( + SOURCEDIRECTORY + classUnderTest.getPackage().getName().replaceAll("\\.", "/")); packageDirectory.mkdirs(); return packageDirectory; } - private File toSourceFile(File packageDirectory, Class type) { - return new File(packageDirectory, type.getName().replaceAll("\\.", "/") + "Tests.java"); - } - - private File toPackageDirectory(Class type) { - return new File(SOURCEDIRECTORY + type.getPackage().getName().replaceAll("\\.", "/")); + private File getSourceFile() { + return new File(packageDirectory, classUnderTest.getSimpleName() + "Tests.java"); } } diff --git a/src/main/java/nl/jssl/autounit/classanalyser/ClassAnalyser.java b/src/main/java/nl/jssl/autounit/classanalyser/ClassAnalyser.java index 0d2d971..0e9b6dc 100644 --- a/src/main/java/nl/jssl/autounit/classanalyser/ClassAnalyser.java +++ b/src/main/java/nl/jssl/autounit/classanalyser/ClassAnalyser.java @@ -6,35 +6,36 @@ import java.util.ArrayList; import java.util.List; import nl.jssl.autounit.inputs.MethodcallArgumentsFactory; -import nl.jssl.autounit.util.Pair; +import nl.jssl.autounit.util.LinkedList; -public class ClassAnalyser { - private Class testTarget; +public class ClassAnalyser { + private Class testTarget; - public ClassAnalyser(Class testTarget) { + public ClassAnalyser(Class testTarget) { this.testTarget = testTarget; } - public ClassResults analyse() { - List classresults = new ArrayList<>(); + public ClassResults analyseAndGetResults() { + List classresults = new ArrayList<>(); + for (Method m : getPublicMethods()) { - MethodCallResults methodresults = recordMethod(m); - classresults.add(methodresults); + classresults.add(analyseMethod(m)); } return new ClassResults(testTarget, classresults); } - private MethodCallResults recordMethod(Method m) { - List inputSet = new MethodcallArgumentsFactory().getInputs(testTarget, m); - MethodcallExecutor methodcallExecutor = new MethodcallExecutor(testTarget, m); - methodcallExecutor.execute(inputSet); - MethodCallResults mcr = methodcallExecutor.getResult(); - return mcr; + private MethodExecutionResults analyseMethod(Method method) { + List inputSet = new MethodcallArgumentsFactory(testTarget).getInputs(method); + + MethodcallExecutor methodcallExecutor = new MethodcallExecutor<>(testTarget, method); + + return methodcallExecutor.executeAndGetResults(inputSet); } List getPublicMethods() { List publicMethods = new ArrayList(); + for (Method m : testTarget.getDeclaredMethods()) { if (Modifier.isPublic(m.getModifiers())) { publicMethods.add(m); diff --git a/src/main/java/nl/jssl/autounit/classanalyser/ClassResults.java b/src/main/java/nl/jssl/autounit/classanalyser/ClassResults.java index 3614353..d063db6 100644 --- a/src/main/java/nl/jssl/autounit/classanalyser/ClassResults.java +++ b/src/main/java/nl/jssl/autounit/classanalyser/ClassResults.java @@ -4,15 +4,15 @@ import java.util.List; public class ClassResults { private final Class type; - private final List methodCallResults; + private final List methodCallResults; - public ClassResults(Class type, List methodCallResults) { + public ClassResults(Class type, List methodCallResults) { super(); this.type = type; this.methodCallResults = methodCallResults; } - public List getMethodCallResults() { + public List getMethodCallResults() { return methodCallResults; } diff --git a/src/main/java/nl/jssl/autounit/classanalyser/CoverageAnalyser.java b/src/main/java/nl/jssl/autounit/classanalyser/CoverageAnalyser.java index 0738596..743db91 100644 --- a/src/main/java/nl/jssl/autounit/classanalyser/CoverageAnalyser.java +++ b/src/main/java/nl/jssl/autounit/classanalyser/CoverageAnalyser.java @@ -17,41 +17,35 @@ import org.jacoco.core.runtime.RuntimeData; import nl.jssl.autounit.util.MemoryClassloader; import nl.jssl.autounit.util.SilentObjectCreator; -public class CoverageAnalyser { - private IRuntime runtime; - private RuntimeData data = new RuntimeData(); +public class CoverageAnalyser { + private final IRuntime runtime; + private final RuntimeData data; + private final Class testTarget; - @SuppressWarnings("unchecked") - public T instrument(Class testTarget) { + public CoverageAnalyser(Class testTarget) { + this.testTarget = testTarget; + data = new RuntimeData(); + runtime = new LoggerRuntime(); + } + + public T instrument() { try { - String targetName = testTarget.getName(); - - runtime = new LoggerRuntime(); - - Instrumenter instr = new Instrumenter(runtime); - byte[] instrumented = instr.instrument(getTargetClass(targetName), targetName); - - data = new RuntimeData(); runtime.startup(data); - MemoryClassloader memoryClassLoader = new MemoryClassloader(); - memoryClassLoader.addDefinition(targetName, instrumented); - Class targetClass = (Class) memoryClassLoader.loadClass(targetName); - - return SilentObjectCreator.create(targetClass); + return getInstrumentedObjectInstance(); } catch (Exception e) { - throw new RuntimeException(e); + throw new AnalysisFailed(e); } } - public InvocationResult analyse(T instrumentedTestTarget, Method method, Object[] inputs) { + public InvocationResult analyse(T instrumentedTestTarget, Method method, Object[] inputs) { try { - Method instanceMethod = getInstrumentedMethod(instrumentedTestTarget, method); - Object output = invoke(instrumentedTestTarget, inputs, instanceMethod); + Object output = invokeMethod(instrumentedTestTarget, inputs, + getInstrumentedMethod(instrumentedTestTarget, method)); // jacoco stuff ExecutionDataStore executionData = executionData(); - + runtime.shutdown(); CoverageBuilder coverageBuilder = coverageBuilder(instrumentedTestTarget, executionData); @@ -62,6 +56,24 @@ public class CoverageAnalyser { } } + @SuppressWarnings("unchecked") + private T getInstrumentedObjectInstance() throws IOException, ClassNotFoundException { + MemoryClassloader memoryClassLoader = getMemoryClassLoaderForClass(getInstrumentedByteCode()); + Class targetClass = (Class) memoryClassLoader.loadClass(testTarget.getName()); + + return SilentObjectCreator.create(targetClass); + } + + private byte[] getInstrumentedByteCode() throws IOException { + return new Instrumenter(runtime).instrument(getTargetClass(), testTarget.getName()); + } + + private MemoryClassloader getMemoryClassLoaderForClass(byte[] instrumentedByteCode) { + MemoryClassloader memoryClassLoader = new MemoryClassloader(); + memoryClassLoader.addDefinition(testTarget.getName(), instrumentedByteCode); + return memoryClassLoader; + } + private ExecutionDataStore executionData() { ExecutionDataStore executionData = new ExecutionDataStore(); SessionInfoStore sessionInfos = new SessionInfoStore(); @@ -69,20 +81,20 @@ public class CoverageAnalyser { return executionData; } - private CoverageBuilder coverageBuilder(T instrumentedTestTarget, ExecutionDataStore executionData) + private CoverageBuilder coverageBuilder(T instrumentedTestTarget, ExecutionDataStore executionData) throws IOException { CoverageBuilder coverageBuilder = new CoverageBuilder(); Analyzer analyzer = new Analyzer(executionData, coverageBuilder); String targetName = instrumentedTestTarget.getClass().getName(); - analyzer.analyzeClass(getTargetClass(targetName), targetName); + analyzer.analyzeClass(getTargetClass(), targetName); return coverageBuilder; } - private Method getInstrumentedMethod(T testTarget, Method method) throws NoSuchMethodException { + private Method getInstrumentedMethod(T testTarget, Method method) throws NoSuchMethodException { return testTarget.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes()); } - private Object invoke(T testTarget, Object[] inputs, Method newInstanceMethod) throws IllegalAccessException { + private Object invokeMethod(T testTarget, Object[] inputs, Method newInstanceMethod) throws IllegalAccessException { Object output; try { output = newInstanceMethod.invoke(testTarget, inputs); @@ -101,8 +113,8 @@ public class CoverageAnalyser { return output; } - private InputStream getTargetClass(String name) { - String resource = '/' + name.replace('.', '/') + ".class"; + private InputStream getTargetClass() { + String resource = '/' + testTarget.getName().replace('.', '/') + ".class"; return getClass().getResourceAsStream(resource); } diff --git a/src/main/java/nl/jssl/autounit/classanalyser/InAndOutput.java b/src/main/java/nl/jssl/autounit/classanalyser/InAndOutput.java index 290142f..b820c0f 100644 --- a/src/main/java/nl/jssl/autounit/classanalyser/InAndOutput.java +++ b/src/main/java/nl/jssl/autounit/classanalyser/InAndOutput.java @@ -1,17 +1,17 @@ package nl.jssl.autounit.classanalyser; -import nl.jssl.autounit.util.Pair; +import nl.jssl.autounit.util.LinkedList; public class InAndOutput { - private final Pair input; + private final LinkedList input; private final Object output; - public InAndOutput(Pair input, Object output) { + public InAndOutput(LinkedList input, Object output) { this.input = input; this.output = output; } - public Pair getInput() { + public LinkedList getInput() { return input; } diff --git a/src/main/java/nl/jssl/autounit/classanalyser/MethodCallResults.java b/src/main/java/nl/jssl/autounit/classanalyser/MethodExecutionResults.java similarity index 87% rename from src/main/java/nl/jssl/autounit/classanalyser/MethodCallResults.java rename to src/main/java/nl/jssl/autounit/classanalyser/MethodExecutionResults.java index 8be1732..f4645b1 100644 --- a/src/main/java/nl/jssl/autounit/classanalyser/MethodCallResults.java +++ b/src/main/java/nl/jssl/autounit/classanalyser/MethodExecutionResults.java @@ -7,21 +7,21 @@ import java.util.List; import org.jacoco.core.analysis.IClassCoverage; -import nl.jssl.autounit.util.Pair; +import nl.jssl.autounit.util.LinkedList; -public class MethodCallResults implements Comparable { +public class MethodExecutionResults implements Comparable { private transient Object testinstance; private transient Method executedMethod; private List contents = new ArrayList(); private transient IClassCoverage coverageResult; - public MethodCallResults(Object testClass, Method m) { + public MethodExecutionResults(Object testClass, Method m) { super(); this.testinstance = testClass; this.executedMethod = m; } - public void addResult(Pair input, Object output) { + public void addResult(LinkedList input, Object output) { contents.add(new InAndOutput(input, output)); } @@ -86,7 +86,7 @@ public class MethodCallResults implements Comparable { } @Override - public int compareTo(MethodCallResults o) { + public int compareTo(MethodExecutionResults o) { return getMethodName().compareTo(o.getMethodName()); } } diff --git a/src/main/java/nl/jssl/autounit/classanalyser/MethodcallExecutor.java b/src/main/java/nl/jssl/autounit/classanalyser/MethodcallExecutor.java index 9462cb3..d75285b 100644 --- a/src/main/java/nl/jssl/autounit/classanalyser/MethodcallExecutor.java +++ b/src/main/java/nl/jssl/autounit/classanalyser/MethodcallExecutor.java @@ -3,30 +3,32 @@ package nl.jssl.autounit.classanalyser; import java.lang.reflect.Method; import java.util.List; -import nl.jssl.autounit.util.Pair; +import nl.jssl.autounit.util.LinkedList; /** - * voert 1 methode uit met wisselende input parameters en bewaart het resultaat. + * Executes 1 method using alternating input parameters and yields execution + * results. * */ -public class MethodcallExecutor { - private Object instrumentedTestTarget; +public class MethodcallExecutor { + private T instrumentedTestTarget; private Method methodUnderTest; - CoverageAnalyser coverageAnalyser = new CoverageAnalyser(); - private MethodCallResults result; + private MethodExecutionResults result; + private final CoverageAnalyser coverageAnalyser; + + public MethodcallExecutor(Class testClass, Method methodUnderTest) { + coverageAnalyser = new CoverageAnalyser(testClass); + this.instrumentedTestTarget = coverageAnalyser.instrument(); - public MethodcallExecutor(Class testClass, Method methodUnderTest) { - super(); - this.instrumentedTestTarget = coverageAnalyser.instrument(testClass); this.methodUnderTest = methodUnderTest; - this.result = new MethodCallResults(instrumentedTestTarget, methodUnderTest); + this.result = new MethodExecutionResults(instrumentedTestTarget, methodUnderTest); } - public MethodCallResults execute(List inputs) { + public MethodExecutionResults executeAndGetResults(List inputs) { InvocationResult lastInvocationResult = null, previous = null; int missedLines = Integer.MAX_VALUE; - for (Pair input : inputs) { + for (LinkedList input : inputs) { previous = lastInvocationResult; lastInvocationResult = analyseMethodCall(methodUnderTest, input); @@ -51,7 +53,7 @@ public class MethodcallExecutor { } private int addInOutputCombinationWhenCoverageIncreases(int missedLines, InvocationResult lastInvocationResult, - Pair input, int missedCount) { + LinkedList input, int missedCount) { if (coverageHasIncreased(missedLines, missedCount)) { missedLines = missedCount; addInterestingInAndOutput(input, lastInvocationResult); @@ -59,7 +61,7 @@ public class MethodcallExecutor { return missedLines; } - private void addInterestingInAndOutput(Pair input, InvocationResult lastInvocationResult) { + private void addInterestingInAndOutput(LinkedList input, InvocationResult lastInvocationResult) { result.addResult(input, lastInvocationResult.getOutput()); } @@ -71,7 +73,7 @@ public class MethodcallExecutor { return missedCount < missedLines; } - private InvocationResult analyseMethodCall(Method methodUnderTest, Pair input) { + private InvocationResult analyseMethodCall(Method methodUnderTest, LinkedList input) { Object[] inputs = replaceNullIndicatorWithNull(input.toArray()); return coverageAnalyser.analyse(instrumentedTestTarget, methodUnderTest, inputs); @@ -86,7 +88,4 @@ public class MethodcallExecutor { return argumentarray; } - public MethodCallResults getResult() { - return result; - } } diff --git a/src/main/java/nl/jssl/autounit/inputs/MethodcallArgumentsFactory.java b/src/main/java/nl/jssl/autounit/inputs/MethodcallArgumentsFactory.java index d33c5c8..da3ed1a 100644 --- a/src/main/java/nl/jssl/autounit/inputs/MethodcallArgumentsFactory.java +++ b/src/main/java/nl/jssl/autounit/inputs/MethodcallArgumentsFactory.java @@ -15,22 +15,24 @@ import nl.jssl.autounit.inputs.primitives.ByteArgumentFactory; import nl.jssl.autounit.inputs.primitives.DoubleArgumentFactory; import nl.jssl.autounit.inputs.primitives.FloatArgumentFactory; import nl.jssl.autounit.inputs.primitives.IntegerArgumentFactory; -import nl.jssl.autounit.util.Pair; +import nl.jssl.autounit.util.LinkedList; import nl.jssl.autounit.util.Permuter; public class MethodcallArgumentsFactory { private final Map, ArgumentFactory> primitivesFactories; + private final Class testTarget; - public MethodcallArgumentsFactory() { + public MethodcallArgumentsFactory(Class testTarget) { + this.testTarget = testTarget; primitivesFactories = new HashMap, ArgumentFactory>(); populateFactories(); } - public List getInputs(Class testTarget, Method m) { - return combine(getArgumentsForAllParameters(testTarget, m)); + public List getInputs(Method method) { + return combine(getArgumentsForAllParameters(method)); } - private List combine(List> inputSetsForAllArguments) { + private List combine(List> inputSetsForAllArguments) { int nrOfParameters = inputSetsForAllArguments.size(); if (nrOfParameters == 0) { return Collections.emptyList(); @@ -42,25 +44,25 @@ public class MethodcallArgumentsFactory { } } - private List makeArgumentsForSingleParameterCall(List> generatedInputSetsForAllArguments) { - List allPossibleArguments = new ArrayList<>(); + private List makeArgumentsForSingleParameterCall(List> generatedInputSetsForAllArguments) { + List allPossibleArguments = new ArrayList<>(); List generatedInputs = generatedInputSetsForAllArguments.iterator().next(); for (Object variable : generatedInputs) { - Pair argument = new Pair(variable); + LinkedList argument = new LinkedList(variable); allPossibleArguments.add(argument); } return allPossibleArguments; } - List> getArgumentsForAllParameters(Class testTarget, Method m) { + List> getArgumentsForAllParameters(Method method) { List> singleInputSets = new ArrayList>(); - for (Class parametertype : m.getParameterTypes()) { - List inputs = tryPrimitives(testTarget, parametertype); + for (Class parametertype : method.getParameterTypes()) { + List inputs = tryPrimitives(parametertype); if (inputs == null) { - inputs = new ObjectArgumentFactory().getObjectArgument(testTarget, parametertype); + inputs = new ObjectArgumentFactory().getObjectArgument(parametertype); } if (inputs != null) { singleInputSets.add(inputs); @@ -69,7 +71,7 @@ public class MethodcallArgumentsFactory { return singleInputSets; } - private ArgumentsForSingleParameter tryPrimitives(Class testTarget, Class parametertype) { + private ArgumentsForSingleParameter tryPrimitives(Class parametertype) { ArgumentFactory inputsFactory = primitivesFactories.get(parametertype); if (inputsFactory != null) { return inputsFactory.getInputs(testTarget); diff --git a/src/main/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactory.java b/src/main/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactory.java index 4d688f5..ea896a5 100644 --- a/src/main/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactory.java +++ b/src/main/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactory.java @@ -2,21 +2,20 @@ package nl.jssl.autounit.inputs.objects; import java.lang.reflect.Method; -import nl.jssl.autounit.inputs.ArgumentsForSingleParameter; -import nl.jssl.autounit.inputs.MethodcallArgumentsFactory; - import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import nl.jssl.autounit.inputs.ArgumentsForSingleParameter; + /** - * Creates arguments if they are objects. Methods that return values are populated like in regular mocking. + * Creates arguments if they are objects. Methods that return values are + * populated like in regular mocking. * */ public class ObjectArgumentFactory { - private MethodcallArgumentsFactory argumentsFactory; - public ArgumentsForSingleParameter getObjectArgument(Class testTarget, Class parametertype) { + public ArgumentsForSingleParameter getObjectArgument(Class parametertype) { ArgumentsForSingleParameter inputs = new ArgumentsForSingleParameter(); Object mock = createMock(parametertype); inputs.add(mock); @@ -44,12 +43,9 @@ public class ObjectArgumentFactory { } - static boolean returnsVoid(Method m) { - Class returnType = m.getReturnType(); + static boolean returnsVoid(Method method) { + Class returnType = method.getReturnType(); return returnType != Void.TYPE; } - public void setArgumentsFactory(MethodcallArgumentsFactory argumentsFactory) { - this.argumentsFactory = argumentsFactory; - } } diff --git a/src/main/java/nl/jssl/autounit/inputs/objects/StringArgumentFactory.java b/src/main/java/nl/jssl/autounit/inputs/objects/StringArgumentFactory.java index 44a4dbd..103d58d 100644 --- a/src/main/java/nl/jssl/autounit/inputs/objects/StringArgumentFactory.java +++ b/src/main/java/nl/jssl/autounit/inputs/objects/StringArgumentFactory.java @@ -1,25 +1,24 @@ package nl.jssl.autounit.inputs.objects; -import javassist.ClassPool; import nl.jssl.autounit.inputs.ArgumentsForSingleParameter; import nl.jssl.autounit.inputs.primitives.ArgumentFactory; import nl.jssl.autounit.util.ConstantpoolReader; /** - * Creates Strings as arguments for a method call. Uses bytecode analysis to scan the class-under-test for "interesting" - * strings and adds them to the argument set. + * Creates Strings as arguments for a method call. Uses bytecode analysis to + * scan the class-under-test for "interesting" strings and adds them to the + * argument set. * * Also adds null to check for NPE. //is this feasible? */ public class StringArgumentFactory implements ArgumentFactory { - private static ConstantpoolReader constantpoolReader = new ConstantpoolReader(ClassPool.getDefault()); @Override public ArgumentsForSingleParameter getInputs(Class testTarget) { ArgumentsForSingleParameter inputs = new ArgumentsForSingleParameter(); inputs.add(null); inputs.add("some"); - inputs.addAll(constantpoolReader.scanStrings(testTarget)); + inputs.addAll(new ConstantpoolReader(testTarget).scanStrings()); return inputs; } diff --git a/src/main/java/nl/jssl/autounit/results/JUnitSourceWriter.java b/src/main/java/nl/jssl/autounit/results/JUnitSourceWriter.java index 432bd1a..a4f3a38 100644 --- a/src/main/java/nl/jssl/autounit/results/JUnitSourceWriter.java +++ b/src/main/java/nl/jssl/autounit/results/JUnitSourceWriter.java @@ -4,7 +4,7 @@ import java.io.PrintStream; import nl.jssl.autounit.classanalyser.ClassResults; import nl.jssl.autounit.classanalyser.InAndOutput; -import nl.jssl.autounit.classanalyser.MethodCallResults; +import nl.jssl.autounit.classanalyser.MethodExecutionResults; public class JUnitSourceWriter extends ResultsWriter { @@ -25,7 +25,7 @@ public class JUnitSourceWriter extends ResultsWriter { out.println(); out.println("public class " + results.getType().getSimpleName() + "Tests {"); Count index = new Count(1); - for (MethodCallResults mcr : results.getMethodCallResults()) { + for (MethodExecutionResults mcr : results.getMethodCallResults()) { for (InAndOutput inout : mcr.getContents()) { writeMethod(index, results, mcr, inout); } @@ -34,7 +34,7 @@ public class JUnitSourceWriter extends ResultsWriter { out.println("}"); } - private void writeMethod(Count index, ClassResults results, MethodCallResults mcr, InAndOutput inout) { + private void writeMethod(Count index, ClassResults results, MethodExecutionResults mcr, InAndOutput inout) { out.println("\t@Test"); out.println("\tpublic void " + mcr.getMethodName() + index.getValue() + "(){"); index.increment(); @@ -54,7 +54,9 @@ public class JUnitSourceWriter extends ResultsWriter { } private String toString(Class type, Object object) { - if (type == String.class) { + if (type.toString().equals("void")) { + return "void"; + } else if (type == String.class) { return "\"" + object + "\""; } else if (type == Double.class || type == double.class) { return object.toString() + "D"; diff --git a/src/main/java/nl/jssl/autounit/results/XStreamResultsWriter.java b/src/main/java/nl/jssl/autounit/results/XStreamResultsWriter.java deleted file mode 100644 index 187385a..0000000 --- a/src/main/java/nl/jssl/autounit/results/XStreamResultsWriter.java +++ /dev/null @@ -1,32 +0,0 @@ -package nl.jssl.autounit.results; - -import java.io.PrintStream; - -import com.thoughtworks.xstream.XStream; - -import nl.jssl.autounit.classanalyser.ClassResults; -import nl.jssl.autounit.classanalyser.InAndOutput; -import nl.jssl.autounit.classanalyser.MethodCallResults; -import nl.jssl.autounit.util.Pair; -import nl.jssl.autounit.util.XStreamArgumentsConverter; - -public class XStreamResultsWriter extends ResultsWriter { - private XStream xstream = new XStream(); - - public XStreamResultsWriter(PrintStream out) { - super(out); - setup(); - } - - @Override - public void write(ClassResults results) { - xstream.toXML(results, out); - } - - private void setup() { - xstream.alias("case", InAndOutput.class); - xstream.alias("results", MethodCallResults.class); - xstream.alias("args", Pair.class); - xstream.registerConverter(new XStreamArgumentsConverter()); - } -} diff --git a/src/main/java/nl/jssl/autounit/util/ConstantpoolReader.java b/src/main/java/nl/jssl/autounit/util/ConstantpoolReader.java index 20ff4e1..075fb76 100644 --- a/src/main/java/nl/jssl/autounit/util/ConstantpoolReader.java +++ b/src/main/java/nl/jssl/autounit/util/ConstantpoolReader.java @@ -9,29 +9,29 @@ import javassist.NotFoundException; import javassist.bytecode.ConstPool; /** + * Reads the constantpool of a class (see jvm spec) */ public class ConstantpoolReader { - private ClassPool pool; + private final static ClassPool pool; + private final Class classToRead; + private final List strings = new ArrayList(); - public ConstantpoolReader(ClassPool pool) { - this.pool = pool; + static { + pool = ClassPool.getDefault(); } - public List scanStrings(Class target) { + public ConstantpoolReader(Class classToRead) { + this.classToRead = classToRead; + } + + public List scanStrings() { CtClass ctClass; try { - ctClass = pool.get(target.getName()); - List strings = new ArrayList(); + ctClass = pool.get(classToRead.getName()); if (isScannable(ctClass)) { ConstPool constPool = ctClass.getClassFile().getConstPool(); - int size = constPool.getSize(); - for (int i = 1; i < size; i++) { - int tag = constPool.getTag(i); - if (tag == ConstPool.CONST_String) { - strings.add(constPool.getStringInfo(i)); - } - } + doScanStrings(constPool); } return strings; } catch (NotFoundException e) { @@ -39,6 +39,16 @@ public class ConstantpoolReader { } } + private void doScanStrings(ConstPool constPool) { + for (int i = 1; i < constPool.getSize(); i++) { + int tag = constPool.getTag(i); + + if (tag == ConstPool.CONST_String) { + strings.add(constPool.getStringInfo(i)); + } + } + } + private boolean isScannable(CtClass ctClass) { return !ctClass.isFrozen(); } diff --git a/src/main/java/nl/jssl/autounit/util/Pair.java b/src/main/java/nl/jssl/autounit/util/LinkedList.java similarity index 74% rename from src/main/java/nl/jssl/autounit/util/Pair.java rename to src/main/java/nl/jssl/autounit/util/LinkedList.java index 78079d0..33a16b2 100644 --- a/src/main/java/nl/jssl/autounit/util/Pair.java +++ b/src/main/java/nl/jssl/autounit/util/LinkedList.java @@ -4,16 +4,16 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -public class Pair implements Iterable { +public class LinkedList implements Iterable { public final Object element1; public final Object element2; - public Pair(Object element1) { + public LinkedList(Object element1) { this.element1 = element1; this.element2 = null; } - public Pair(Object element1, Object element2) { + public LinkedList(Object element1, Object element2) { super(); this.element1 = element1; this.element2 = element2; @@ -22,15 +22,15 @@ public class Pair implements Iterable { public int depth() { int d = 0; if (element2 != null) { - if (element2 instanceof Pair) { - d += 1 + ((Pair) element2).depth(); + if (element2 instanceof LinkedList) { + d += 1 + ((LinkedList) element2).depth(); } else { d += 1; } } if (element1 != null) { - if (element1 instanceof Pair) { - d += 1 + ((Pair) element1).depth(); + if (element1 instanceof LinkedList) { + d += 1 + ((LinkedList) element1).depth(); } else { d += 1; } @@ -57,8 +57,8 @@ public class Pair implements Iterable { } private void add(Object element, List list) { - if (element instanceof Pair) { - Pair pair = (Pair) element; + if (element instanceof LinkedList) { + LinkedList pair = (LinkedList) element; add(pair.element1, list); add(pair.element2, list); } else { diff --git a/src/main/java/nl/jssl/autounit/util/Permuter.java b/src/main/java/nl/jssl/autounit/util/Permuter.java index 86c5b59..8b40e2c 100644 --- a/src/main/java/nl/jssl/autounit/util/Permuter.java +++ b/src/main/java/nl/jssl/autounit/util/Permuter.java @@ -10,24 +10,30 @@ import java.util.List; */ public class Permuter { - public static List permute(List> elements) { + public static List permute(List> elements) { if (elements.size() >= 2) { - List result = permutePairs(elements.remove(0), elements.remove(0)); + List result = permutePairs(elements.remove(0), elements.remove(0)); + + result = permuteRest(elements, result); - for (List element : elements) { - result = permutePairs(element, result); - } return result; } else { throw new IllegalArgumentException("need at least 2"); } } - private static List permutePairs(List list1, List list2) { - List pairs = new ArrayList(); + private static List permuteRest(List> elements, List result) { + for (List element : elements) { + result = permutePairs(element, result); + } + return result; + } + + private static List permutePairs(List list1, List list2) { + List pairs = new ArrayList(); for (Object element1 : list1) { for (Object element2 : list2) { - pairs.add(new Pair(element1, element2)); + pairs.add(new LinkedList(element1, element2)); } } return pairs; diff --git a/src/main/java/nl/jssl/autounit/util/SilentObjectCreator.java b/src/main/java/nl/jssl/autounit/util/SilentObjectCreator.java index 1a0466b..1591ee8 100644 --- a/src/main/java/nl/jssl/autounit/util/SilentObjectCreator.java +++ b/src/main/java/nl/jssl/autounit/util/SilentObjectCreator.java @@ -1,7 +1,9 @@ package nl.jssl.autounit.util; import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import nl.jssl.autounit.classanalyser.AnalysisFailed; import sun.reflect.ReflectionFactory; /** @@ -16,14 +18,20 @@ public class SilentObjectCreator { public static T create(Class clazz, Class parent) { try { - ReflectionFactory rf = ReflectionFactory.getReflectionFactory(); - Constructor objDef = parent.getDeclaredConstructor(); - Constructor intConstr = (Constructor) rf.newConstructorForSerialization(clazz, objDef); - return clazz.cast(intConstr.newInstance()); - } catch (RuntimeException e) { - throw e; - } catch (Exception e) { - throw new IllegalStateException("Cannot create object", e); + return tryCreateInstance(clazz, parent); + } catch (NoSuchMethodException | InstantiationException | IllegalAccessException + | InvocationTargetException e) { + throw new AnalysisFailed("Cannot create object", e); } } + + @SuppressWarnings("unchecked") + private static T tryCreateInstance(Class clazz, Class parent) + throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException { + + ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory(); + Constructor objDef = parent.getDeclaredConstructor(); + Constructor intConstr = (Constructor) reflectionFactory.newConstructorForSerialization(clazz, objDef); + return clazz.cast(intConstr.newInstance()); + } } \ No newline at end of file diff --git a/src/main/java/nl/jssl/autounit/util/XStreamArgumentsConverter.java b/src/main/java/nl/jssl/autounit/util/XStreamArgumentsConverter.java deleted file mode 100644 index 2959650..0000000 --- a/src/main/java/nl/jssl/autounit/util/XStreamArgumentsConverter.java +++ /dev/null @@ -1,31 +0,0 @@ -package nl.jssl.autounit.util; - -import com.thoughtworks.xstream.converters.Converter; -import com.thoughtworks.xstream.converters.MarshallingContext; -import com.thoughtworks.xstream.converters.UnmarshallingContext; -import com.thoughtworks.xstream.io.HierarchicalStreamReader; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; - -public class XStreamArgumentsConverter implements Converter { - - @SuppressWarnings("rawtypes") - public boolean canConvert(Class clazz) { - return (clazz == Pair.class); - } - - public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) { - Pair arguments = (Pair) value; - int index = 1; - for (Object arg : arguments) { - writer.startNode("arg" + index); - writer.setValue(arg.toString()); - writer.endNode(); - } - - } - - public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) { - return null; - } - -} diff --git a/src/test/java/nl/jssl/autounit/classanalyser/PrimtiveTypeTests.java b/src/test/java/nl/jssl/autounit/classanalyser/PrimtiveTypeTests.java index 41f6d79..d55db6f 100644 --- a/src/test/java/nl/jssl/autounit/classanalyser/PrimtiveTypeTests.java +++ b/src/test/java/nl/jssl/autounit/classanalyser/PrimtiveTypeTests.java @@ -17,15 +17,15 @@ import nl.jssl.autounit.testclasses.IntArguments; public class PrimtiveTypeTests { @Test public void testGetPublicMethods() throws NoSuchMethodException, SecurityException { - List publicMethods = new ClassAnalyser(IntArguments.class).getPublicMethods(); + List publicMethods = new ClassAnalyser<>(IntArguments.class).getPublicMethods(); assertEquals(2, publicMethods.size()); } @Test public void testIntegerArgument() { - Iterator methodCallResults = new TreeSet<>( - new ClassAnalyser(IntArguments.class).analyse().getMethodCallResults()).iterator(); + Iterator methodCallResults = new TreeSet<>( + new ClassAnalyser<>(IntArguments.class).analyseAndGetResults().getMethodCallResults()).iterator(); assertEquals("public java.lang.String evenOrUneven(int arg1,int arg2)", methodCallResults.next().getMethodSignature()); @@ -34,19 +34,22 @@ public class PrimtiveTypeTests { @Test public void testBooleanArgument() { - MethodCallResults mcr = new ClassAnalyser(BooleanArguments.class).analyse().getMethodCallResults().get(0); + MethodExecutionResults mcr = new ClassAnalyser<>(BooleanArguments.class).analyseAndGetResults() + .getMethodCallResults().get(0); assertEquals(mcr.getMethodSignature(), "public java.lang.String getText(boolean arg1,boolean arg2)"); } @Test public void testByteArgument() { - MethodCallResults mcr = new ClassAnalyser(ByteArguments.class).analyse().getMethodCallResults().get(0); + MethodExecutionResults mcr = new ClassAnalyser<>(ByteArguments.class).analyseAndGetResults().getMethodCallResults() + .get(0); assertEquals(mcr.getMethodSignature(), "public int getDouble(byte arg1)"); } @Test public void testFloatArgument() { - MethodCallResults mcr = new ClassAnalyser(FloatArguments.class).analyse().getMethodCallResults().get(0); + MethodExecutionResults mcr = new ClassAnalyser<>(FloatArguments.class).analyseAndGetResults().getMethodCallResults() + .get(0); assertEquals(mcr.getMethodSignature(), "public int round(float arg1)"); } diff --git a/src/test/java/nl/jssl/autounit/classanalyser/StringTypeTests.java b/src/test/java/nl/jssl/autounit/classanalyser/StringTypeTests.java index 1f22ed7..f8311a8 100644 --- a/src/test/java/nl/jssl/autounit/classanalyser/StringTypeTests.java +++ b/src/test/java/nl/jssl/autounit/classanalyser/StringTypeTests.java @@ -12,8 +12,9 @@ public class StringTypeTests { @Test public void testStringArgumentShouldBeTjeempie() { - List results = new ClassAnalyser(StringArguments.class).analyse().getMethodCallResults(); - MethodCallResults mcr = results.get(0); + List results = new ClassAnalyser<>(StringArguments.class).analyseAndGetResults() + .getMethodCallResults(); + MethodExecutionResults mcr = results.get(0); String methodSignature = mcr.getMethodSignature(); assertEquals("public boolean getBar(java.lang.String arg1)", methodSignature); System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines"); diff --git a/src/test/java/nl/jssl/autounit/inputs/objects/JavaBeanTests.java b/src/test/java/nl/jssl/autounit/inputs/objects/JavaBeanTests.java index 9f5f061..78c8866 100644 --- a/src/test/java/nl/jssl/autounit/inputs/objects/JavaBeanTests.java +++ b/src/test/java/nl/jssl/autounit/inputs/objects/JavaBeanTests.java @@ -7,14 +7,15 @@ import java.util.TreeSet; import org.junit.Test; +import nl.jssl.autounit.JUnitTestCreator; import nl.jssl.autounit.classanalyser.ClassAnalyser; -import nl.jssl.autounit.classanalyser.MethodCallResults; +import nl.jssl.autounit.classanalyser.MethodExecutionResults; import nl.jssl.autounit.testclasses.SomeBean; public class JavaBeanTests { @Test public void testJavaBeanArgument() { - Iterator results = getSortedAnalysisResults().iterator(); + Iterator results = getSortedAnalysisResults().iterator(); assertEquals("public int getBar()", results.next().getMethodSignature()); assertEquals("public java.lang.String getFoo()", results.next().getMethodSignature()); @@ -22,7 +23,12 @@ public class JavaBeanTests { assertEquals("public void setFoo(java.lang.String arg1)", results.next().getMethodSignature()); } - private TreeSet getSortedAnalysisResults() { - return new TreeSet<>(new ClassAnalyser(SomeBean.class).analyse().getMethodCallResults()); + private TreeSet getSortedAnalysisResults() { + return new TreeSet<>(new ClassAnalyser<>(SomeBean.class).analyseAndGetResults().getMethodCallResults()); + } + + @Test + public void getUnittest() { + new JUnitTestCreator<>(SomeBean.class).create(); } } diff --git a/src/test/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactoryTests.java b/src/test/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactoryTests.java index ab33f3f..3df53f3 100644 --- a/src/test/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactoryTests.java +++ b/src/test/java/nl/jssl/autounit/inputs/objects/ObjectArgumentFactoryTests.java @@ -1,5 +1,6 @@ package nl.jssl.autounit.inputs.objects; +import static nl.jssl.autounit.inputs.objects.ObjectArgumentFactory.returnsVoid; import static org.junit.Assert.assertEquals; import java.lang.reflect.Method; @@ -9,12 +10,11 @@ import org.junit.Test; public class ObjectArgumentFactoryTests { @Test public void testVoidReturn() throws NoSuchMethodException, SecurityException { - ObjectArgumentFactory o = new ObjectArgumentFactory(); Method testVoidReturnMethod = ObjectArgumentFactoryTests.class.getMethod("testVoidReturn", new Class[] {}); - assertEquals(false, o.returnsVoid(testVoidReturnMethod)); + assertEquals(false, returnsVoid(testVoidReturnMethod)); Method getBarMethod = ObjectArgumentFactoryTests.class.getMethod("getBar", new Class[] {}); - assertEquals(true, o.returnsVoid(getBarMethod)); + assertEquals(true, returnsVoid(getBarMethod)); } public String getBar() { diff --git a/src/test/java/nl/jssl/autounit/inspect/ConstantpoolReaderTest.java b/src/test/java/nl/jssl/autounit/inspect/ConstantpoolReaderTest.java index c5bcf7d..f8b1c07 100644 --- a/src/test/java/nl/jssl/autounit/inspect/ConstantpoolReaderTest.java +++ b/src/test/java/nl/jssl/autounit/inspect/ConstantpoolReaderTest.java @@ -4,7 +4,6 @@ import java.util.List; import org.junit.Test; -import javassist.ClassPool; import javassist.NotFoundException; import nl.jssl.autounit.testclasses.IntArguments; import nl.jssl.autounit.util.ConstantpoolReader; @@ -12,10 +11,8 @@ import nl.jssl.autounit.util.ConstantpoolReader; public class ConstantpoolReaderTest { @Test public void test() throws NotFoundException { - ClassPool classPool = new ClassPool(); - classPool.appendClassPath("bin"); - ConstantpoolReader reader = new ConstantpoolReader(classPool); - List strings = reader.scanStrings(IntArguments.class); + ConstantpoolReader reader = new ConstantpoolReader(IntArguments.class); + List strings = reader.scanStrings(); for (String string : strings) { System.out.println(string); } diff --git a/src/test/java/nl/jssl/autounit/util/PairTests.java b/src/test/java/nl/jssl/autounit/util/PairTests.java index 35a4cd6..f2b75d5 100644 --- a/src/test/java/nl/jssl/autounit/util/PairTests.java +++ b/src/test/java/nl/jssl/autounit/util/PairTests.java @@ -7,19 +7,19 @@ import org.junit.Test; public class PairTests { @Test public void testDepth1() { - Pair p = new Pair("1"); + LinkedList p = new LinkedList("1"); assertEquals(1, p.depth()); } @Test public void testDepth2() { - Pair p = new Pair(new Pair("1")); + LinkedList p = new LinkedList(new LinkedList("1")); assertEquals(2, p.depth()); } @Test public void testDepth3() { - Pair p = new Pair(new Pair(new Pair("1"))); + LinkedList p = new LinkedList(new LinkedList(new LinkedList("1"))); assertEquals(3, p.depth()); } } diff --git a/src/test/java/nl/jssl/autounit/util/PermuterTests.java b/src/test/java/nl/jssl/autounit/util/PermuterTests.java index fddeb22..8cf4938 100644 --- a/src/test/java/nl/jssl/autounit/util/PermuterTests.java +++ b/src/test/java/nl/jssl/autounit/util/PermuterTests.java @@ -21,7 +21,7 @@ public class PermuterTests { List> outer = new ArrayList>(); outer.add(integers); outer.add(strings); - List permuted = Permuter.permute(outer); + List permuted = Permuter.permute(outer); assertEquals("1-A-", permuted.get(0).toString()); assertEquals("1-B-", permuted.get(1).toString()); @@ -46,7 +46,7 @@ public class PermuterTests { outer.add(strings); outer.add(vogons); - List permuted = Permuter.permute(outer); + List permuted = Permuter.permute(outer); assertEquals("Vogon Jeltz-1-A-", permuted.get(0).toString()); assertEquals("Vogon Jeltz-1-B-", permuted.get(1).toString()); assertEquals("Vogon Jeltz-2-A-", permuted.get(2).toString());