Compare commits
10 commits
0855c56fa7
...
345f769bc0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
345f769bc0 | ||
|
|
5659e497f8 | ||
|
|
44cb4039ac | ||
|
|
a86c365616 | ||
|
|
07021dd9a9 | ||
|
|
c74da14533 | ||
|
|
7bd69290c4 | ||
|
|
b85037666a | ||
|
|
d9a3df8277 | ||
|
|
ed603109cc |
51 changed files with 1012 additions and 784 deletions
|
|
@ -1,4 +1,6 @@
|
|||
autounit
|
||||
Autounit
|
||||
========
|
||||
|
||||
autounit
|
||||
Autounit is an attempt to make my life easier when writing code. It should provide me with unit tests for any given type.
|
||||
This attempt is destined to fail, as it would require strong AI to understand the intent of a piece of code. Even for humans this is often a daunting task.
|
||||
Nevertheless, let's see where this goes...
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ repositories{
|
|||
mavenCentral()
|
||||
}
|
||||
|
||||
sourceCompatibility = "1.6"
|
||||
targetCompatibility = "1.6"
|
||||
sourceCompatibility = "1.8"
|
||||
targetCompatibility = "1.8"
|
||||
|
||||
sourceSets {
|
||||
test {
|
||||
|
|
@ -23,7 +23,7 @@ dependencies{
|
|||
compile 'javassist:javassist:3.12.1.GA'
|
||||
compile 'com.thoughtworks.xstream:xstream:1.4.7'
|
||||
compile 'org.mockito:mockito-all:1.9.5'
|
||||
testCompile 'junit:junit:4.11'
|
||||
testCompile 'org.jacoco:org.jacoco.core:0.7.1.201405082137'
|
||||
compile 'org.jacoco:org.jacoco.core:0.7.1.201405082137'
|
||||
|
||||
testCompile 'junit:junit:4.11'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* record: records in and outputs
|
||||
*
|
||||
* assertUnchangedBehaviour: raises an error when recorded inputs do no lead to
|
||||
* recorded outputs
|
||||
*/
|
||||
public class AutoTester {
|
||||
ResultsWriter resultsWriter = new ResultsWriter();
|
||||
|
||||
public Map<String, MethodCallResults> record(Class<?> instance) {
|
||||
Map<String, MethodCallResults> results = new Recorder(instance).record();
|
||||
resultsWriter.write(instance.getName(), results);
|
||||
return results;
|
||||
}
|
||||
|
||||
private Map<String, MethodCallResults> load(String classname) {
|
||||
try {
|
||||
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(classname + ".dat"));
|
||||
Map<String, MethodCallResults> results = (Map<String, MethodCallResults>) objectInputStream.readObject();
|
||||
objectInputStream.close();
|
||||
return results;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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("c:\\workspaces\\autounit\\autounit\\bin");
|
||||
classPool.appendClassPath(getClasspathSettingOrEclipseDefault());
|
||||
} catch (NotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return classPool;
|
||||
}
|
||||
|
||||
private static String getClasspathSettingOrEclipseDefault() {
|
||||
return System.getProperty("autounit.cp", "bin");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import nl.jssl.autounit.utils.MemoryClassloader;
|
||||
import nl.jssl.autounit.utils.SilentObjectCreator;
|
||||
|
||||
import org.jacoco.core.analysis.Analyzer;
|
||||
import org.jacoco.core.analysis.CoverageBuilder;
|
||||
import org.jacoco.core.analysis.IClassCoverage;
|
||||
import org.jacoco.core.data.ExecutionDataStore;
|
||||
import org.jacoco.core.data.SessionInfoStore;
|
||||
import org.jacoco.core.instr.Instrumenter;
|
||||
import org.jacoco.core.runtime.IRuntime;
|
||||
import org.jacoco.core.runtime.LoggerRuntime;
|
||||
import org.jacoco.core.runtime.RuntimeData;
|
||||
|
||||
public class CoverageAnalyser {
|
||||
private IRuntime runtime;
|
||||
private RuntimeData data = new RuntimeData();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T instrument(Class<T> testTarget) {
|
||||
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<T> targetClass = (Class<T>) memoryClassLoader.loadClass(targetName);
|
||||
|
||||
return SilentObjectCreator.create(targetClass);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public <T> InvocationResult analyse(T instrumentedTestTarget, Method method, Object[] inputs) {
|
||||
try {
|
||||
Method instanceMethod = getInstrumentedMethod(instrumentedTestTarget, method);
|
||||
Object output = invoke(instrumentedTestTarget, inputs, instanceMethod);
|
||||
|
||||
// jacoco stuff
|
||||
ExecutionDataStore executionData = new ExecutionDataStore();
|
||||
SessionInfoStore sessionInfos = new SessionInfoStore();
|
||||
data.collect(executionData, sessionInfos, false);
|
||||
runtime.shutdown();
|
||||
|
||||
CoverageBuilder coverageBuilder = new CoverageBuilder();
|
||||
Analyzer analyzer = new Analyzer(executionData, coverageBuilder);
|
||||
String targetName = instrumentedTestTarget.getClass().getName();
|
||||
analyzer.analyzeClass(getTargetClass(targetName), targetName);
|
||||
|
||||
return new InvocationResult(coverageBuilder.getClasses().iterator().next(), output);
|
||||
} catch (Exception e) {
|
||||
throw new ExecutionException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> Method getInstrumentedMethod(T testTarget, Method method) throws NoSuchMethodException {
|
||||
return testTarget.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||
}
|
||||
|
||||
private <T> Object invoke(T testTarget, Object[] inputs, Method newInstanceMethod) throws IllegalAccessException {
|
||||
Object output;
|
||||
try {
|
||||
output = newInstanceMethod.invoke(testTarget, inputs);
|
||||
} catch (InvocationTargetException i) {
|
||||
StackTraceElement stacktraceElement = i.getTargetException().getStackTrace()[0];
|
||||
String info = stacktraceElement.getClassName() + ":" + stacktraceElement.getLineNumber();
|
||||
output = i.getTargetException().getClass().getName() + "(" + i.getTargetException().getMessage() + ") at "
|
||||
+ info;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private InputStream getTargetClass(String name) {
|
||||
String resource = '/' + name.replace('.', '/') + ".class";
|
||||
return getClass().getResourceAsStream(resource);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InvocationResult {
|
||||
public final IClassCoverage coverage;
|
||||
public final Object output;
|
||||
|
||||
public InvocationResult(IClassCoverage coverage, Object output) {
|
||||
super();
|
||||
this.coverage = coverage;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
@SuppressWarnings("serial")
|
||||
public class ExecutionException extends RuntimeException {
|
||||
|
||||
public ExecutionException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ExecutionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public ExecutionException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public ExecutionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ExecutionException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
public class InAndOutput {
|
||||
private final Object input;
|
||||
private final Object output;
|
||||
|
||||
public InAndOutput(Object input, Object output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public Object getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public Object getOutput() {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
55
src/main/java/nl/jssl/autounit/JUnitTestCreator.java
Normal file
55
src/main/java/nl/jssl/autounit/JUnitTestCreator.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
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<T> {
|
||||
|
||||
private static final String SOURCEDIRECTORY = "src/outcome/java/";
|
||||
private final Class<T> classUnderTest;
|
||||
private final File packageDirectory;
|
||||
|
||||
public JUnitTestCreator(Class<T> type) {
|
||||
this.classUnderTest = type;
|
||||
packageDirectory = createPackageDirectory();
|
||||
}
|
||||
|
||||
public void create() {
|
||||
try {
|
||||
writeSourceFile();
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeSourceFile() throws FileNotFoundException {
|
||||
ClassResults results = new ClassAnalyser<>(classUnderTest).analyseAndGetResults();
|
||||
getSourceWriter(packageDirectory).write(results);
|
||||
}
|
||||
|
||||
private JUnitSourceWriter getSourceWriter(File packageDirectory) throws FileNotFoundException {
|
||||
return new JUnitSourceWriter(new PrintStream(new FileOutputStream(getSourceFile())));
|
||||
}
|
||||
|
||||
private File createPackageDirectory() {
|
||||
File packageDirectory = new File(
|
||||
SOURCEDIRECTORY + classUnderTest.getPackage().getName().replaceAll("\\.", "/"));
|
||||
packageDirectory.mkdirs();
|
||||
return packageDirectory;
|
||||
}
|
||||
|
||||
private File getSourceFile() {
|
||||
return new File(packageDirectory, classUnderTest.getSimpleName() + "Tests.java");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jacoco.core.analysis.IClassCoverage;
|
||||
|
||||
public class MethodCallResults {
|
||||
private transient Object testinstance;
|
||||
private transient Method executedMethod;
|
||||
private List<InAndOutput> contents = new ArrayList<InAndOutput>();
|
||||
private transient IClassCoverage coverageResult;
|
||||
|
||||
public MethodCallResults(Object testClass, Method m) {
|
||||
super();
|
||||
this.testinstance = testClass;
|
||||
this.executedMethod = m;
|
||||
}
|
||||
|
||||
public void addResult(Object input, Object output) {
|
||||
contents.add(new InAndOutput(input, output));
|
||||
}
|
||||
|
||||
public List<InAndOutput> getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public Object getTestinstance() {
|
||||
return testinstance;
|
||||
}
|
||||
|
||||
public Method getExecutedMethod() {
|
||||
return executedMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getReport();
|
||||
}
|
||||
|
||||
public void setCoverageResult(IClassCoverage coverageResult) {
|
||||
this.coverageResult = coverageResult;
|
||||
}
|
||||
|
||||
public IClassCoverage getCoverageResult() {
|
||||
return coverageResult;
|
||||
}
|
||||
|
||||
public String getReport() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (InAndOutput inAndOutput : contents) {
|
||||
s.append(inAndOutput.getInput() + " => " + inAndOutput.getOutput() + "\n");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import nl.jssl.autounit.utils.Permuter.Tuple;
|
||||
|
||||
/**
|
||||
* voert 1 methode uit met wisselende input parameters en bewaart het resultaat.
|
||||
*
|
||||
*/
|
||||
public class MethodcallExecutor {
|
||||
private Object instrumentedTestTarget;
|
||||
private Method m;
|
||||
CoverageAnalyser coverageAnalyser = new CoverageAnalyser();
|
||||
private MethodCallResults result;
|
||||
|
||||
public MethodcallExecutor(Class<?> testClass, Method m) {
|
||||
super();
|
||||
this.instrumentedTestTarget = coverageAnalyser.instrument(testClass);
|
||||
this.m = m;
|
||||
this.result = new MethodCallResults(instrumentedTestTarget, m);
|
||||
}
|
||||
|
||||
public MethodCallResults execute(List<Tuple> inputs) {
|
||||
int missedLines = Integer.MAX_VALUE;
|
||||
InvocationResult lastInvocationResult = null, previous = null;
|
||||
for (Tuple input : inputs) {
|
||||
previous = lastInvocationResult;
|
||||
lastInvocationResult = analyseMethodCall(m, input);
|
||||
int missedCount = lastInvocationResult.coverage.getLineCounter().getMissedCount();
|
||||
if (missedCount < missedLines) { // coverage increases, this is an
|
||||
// interesting input
|
||||
missedLines = missedCount;
|
||||
result.addResult(input, lastInvocationResult.output);
|
||||
}
|
||||
if (missedCount == 0) { // coverage = 100%: done
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastInvocationResult != null) {
|
||||
if (previous == null) {
|
||||
result.setCoverageResult(lastInvocationResult.coverage);
|
||||
} else {
|
||||
result.setCoverageResult(previous.coverage);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private InvocationResult analyseMethodCall(Method m, Tuple input) {
|
||||
Object[] argumentarray = input.toArray();
|
||||
for (int i = 0; i < argumentarray.length; i++) {
|
||||
if (argumentarray[i].toString().equals("autounit:[NULL]")) {
|
||||
argumentarray[i] = null;
|
||||
}
|
||||
}
|
||||
return coverageAnalyser.analyse(instrumentedTestTarget, m, argumentarray);
|
||||
}
|
||||
|
||||
public MethodCallResults getResult() {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public class Player {
|
||||
final private Object testinstance;
|
||||
|
||||
private Player(Object testinstance) {
|
||||
super();
|
||||
this.testinstance = testinstance;
|
||||
}
|
||||
|
||||
public void playback(Map<String, List<MethodCallResults>> recordedResults) {
|
||||
for (Entry<String, List<MethodCallResults>> entry: recordedResults.entrySet()) {
|
||||
getInputs(entry.getValue());
|
||||
// new Executor(testinstance,getMethod(entry.getKey()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getInputs(List<MethodCallResults> value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import nl.jssl.autounit.inputs.MethodcallArgumentsFactory;
|
||||
import nl.jssl.autounit.utils.Permuter.Tuple;
|
||||
|
||||
public class Recorder {
|
||||
private Class<?> testTarget;
|
||||
|
||||
public Recorder(Class<?> testTarget) {
|
||||
this.testTarget = testTarget;
|
||||
}
|
||||
|
||||
public Map<String, MethodCallResults> record() {
|
||||
Map<String, MethodCallResults> classresults = new HashMap<String, MethodCallResults>();
|
||||
for (Method m : getPublicMethods()) {
|
||||
MethodCallResults methodresults = recordMethod(m);
|
||||
classresults.put(getMethodSignature(m), methodresults);
|
||||
}
|
||||
return classresults;
|
||||
}
|
||||
|
||||
private String getMethodSignature(Method m) {
|
||||
String signature = Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getName() + " " + m.getName()
|
||||
+ "(";
|
||||
int index = 1;
|
||||
Class<?>[] parameterTypes = m.getParameterTypes();
|
||||
for (Class<?> type : parameterTypes) {
|
||||
signature += type.getName() + " arg" + (index++);
|
||||
if (index <= parameterTypes.length) {
|
||||
signature += ",";
|
||||
}
|
||||
}
|
||||
signature += ")";
|
||||
return signature;
|
||||
}
|
||||
|
||||
private MethodCallResults recordMethod(Method m) {
|
||||
List<Tuple> inputSet = new MethodcallArgumentsFactory().getInputs(testTarget, m);
|
||||
MethodcallExecutor methodcallExecutor = new MethodcallExecutor(testTarget, m);
|
||||
methodcallExecutor.execute(inputSet);
|
||||
return methodcallExecutor.getResult();
|
||||
}
|
||||
|
||||
List<Method> getPublicMethods() {
|
||||
List<Method> publicMethods = new ArrayList<Method>();
|
||||
for (Method m : testTarget.getDeclaredMethods()) {
|
||||
if (Modifier.isPublic(m.getModifiers())) {
|
||||
publicMethods.add(m);
|
||||
}
|
||||
}
|
||||
return publicMethods;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Map;
|
||||
|
||||
import nl.jssl.autounit.utils.Permuter.Tuple;
|
||||
import nl.jssl.autounit.utils.XStreamArgumentsConverter;
|
||||
|
||||
import com.thoughtworks.xstream.XStream;
|
||||
|
||||
public class ResultsWriter {
|
||||
XStream xstream = new XStream();
|
||||
|
||||
public ResultsWriter() {
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
xstream.alias("case", InAndOutput.class);
|
||||
xstream.alias("results", MethodCallResults.class);
|
||||
xstream.alias("args", Tuple.class);
|
||||
|
||||
xstream.registerConverter(new XStreamArgumentsConverter());
|
||||
}
|
||||
|
||||
public void write(String classname, Map<String, MethodCallResults> results) {
|
||||
try {
|
||||
xstream.toXML(results, new FileOutputStream(classname + ".xml"));
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
@SuppressWarnings("serial")
|
||||
public class AnalysisFailed extends RuntimeException {
|
||||
|
||||
public AnalysisFailed() {
|
||||
super();
|
||||
}
|
||||
|
||||
public AnalysisFailed(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
public AnalysisFailed(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public AnalysisFailed(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public AnalysisFailed(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nl.jssl.autounit.inputs.MethodcallArgumentsFactory;
|
||||
import nl.jssl.autounit.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Analyses the class you want to create tests for.
|
||||
*/
|
||||
public class ClassAnalyser<T> {
|
||||
private Class<T> testTarget;
|
||||
|
||||
public ClassAnalyser(Class<T> testTarget) {
|
||||
this.testTarget = testTarget;
|
||||
}
|
||||
|
||||
public ClassResults analyseAndGetResults() {
|
||||
List<MethodExecutionResults> classresults = new ArrayList<>();
|
||||
|
||||
for (Method m : getPublicMethods()) {
|
||||
classresults.add(analyseMethod(m));
|
||||
}
|
||||
|
||||
return new ClassResults(testTarget, classresults);
|
||||
}
|
||||
|
||||
private MethodExecutionResults analyseMethod(Method method) {
|
||||
List<LinkedList> inputSet = new MethodcallArgumentsFactory(testTarget).getInputs(method);
|
||||
|
||||
MethodcallExecutor<T> methodcallExecutor = new MethodcallExecutor<>(testTarget, method);
|
||||
|
||||
return methodcallExecutor.executeAndGetResults(inputSet);
|
||||
}
|
||||
|
||||
List<Method> getPublicMethods() {
|
||||
List<Method> publicMethods = new ArrayList<Method>();
|
||||
|
||||
for (Method m : testTarget.getDeclaredMethods()) {
|
||||
if (Modifier.isPublic(m.getModifiers())) {
|
||||
publicMethods.add(m);
|
||||
}
|
||||
}
|
||||
return publicMethods;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ClassResults {
|
||||
private final Class<?> type;
|
||||
private final List<MethodExecutionResults> methodCallResults;
|
||||
|
||||
public ClassResults(Class<?> type, List<MethodExecutionResults> methodCallResults) {
|
||||
super();
|
||||
this.type = type;
|
||||
this.methodCallResults = methodCallResults;
|
||||
}
|
||||
|
||||
public List<MethodExecutionResults> getMethodCallResults() {
|
||||
return methodCallResults;
|
||||
}
|
||||
|
||||
public Class<?> getType() {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.jacoco.core.analysis.Analyzer;
|
||||
import org.jacoco.core.analysis.CoverageBuilder;
|
||||
import org.jacoco.core.data.ExecutionDataStore;
|
||||
import org.jacoco.core.data.SessionInfoStore;
|
||||
import org.jacoco.core.instr.Instrumenter;
|
||||
import org.jacoco.core.runtime.IRuntime;
|
||||
import org.jacoco.core.runtime.LoggerRuntime;
|
||||
import org.jacoco.core.runtime.RuntimeData;
|
||||
|
||||
import nl.jssl.autounit.util.MemoryClassloader;
|
||||
import nl.jssl.autounit.util.SilentObjectCreator;
|
||||
|
||||
/**
|
||||
* When creating tests, increasing coverage indicates a good test. Hence a
|
||||
* CoverageAnalyser. It uses Jacoco (http://eclemma.org/jacoco/), the java
|
||||
* interface for eclemma.
|
||||
*/
|
||||
public class CoverageAnalyser<T> {
|
||||
private final IRuntime runtime;
|
||||
private final RuntimeData data;
|
||||
private final Class<T> testTarget;
|
||||
|
||||
public CoverageAnalyser(Class<T> testTarget) {
|
||||
this.testTarget = testTarget;
|
||||
data = new RuntimeData();
|
||||
runtime = new LoggerRuntime();
|
||||
}
|
||||
|
||||
public T instrument() {
|
||||
try {
|
||||
runtime.startup(data);
|
||||
|
||||
return getInstrumentedObjectInstance();
|
||||
} catch (Exception e) {
|
||||
throw new AnalysisFailed(e);
|
||||
}
|
||||
}
|
||||
|
||||
public InvocationResult analyse(T instrumentedTestTarget, Method method, Object[] inputs) {
|
||||
try {
|
||||
Object output = invokeMethod(instrumentedTestTarget, inputs,
|
||||
getInstrumentedMethod(instrumentedTestTarget, method));
|
||||
|
||||
// jacoco stuff
|
||||
ExecutionDataStore executionData = executionData();
|
||||
|
||||
runtime.shutdown();
|
||||
|
||||
CoverageBuilder coverageBuilder = coverageBuilder(instrumentedTestTarget, executionData);
|
||||
|
||||
return new InvocationResult(coverageBuilder.getClasses().iterator().next(), output);
|
||||
} catch (Exception e) {
|
||||
throw new AnalysisFailed(e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private T getInstrumentedObjectInstance() throws IOException, ClassNotFoundException {
|
||||
MemoryClassloader memoryClassLoader = getMemoryClassLoaderForClass(getInstrumentedByteCode());
|
||||
Class<T> targetClass = (Class<T>) 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();
|
||||
data.collect(executionData, sessionInfos, false);
|
||||
return 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);
|
||||
return coverageBuilder;
|
||||
}
|
||||
|
||||
private Method getInstrumentedMethod(T testTarget, Method method) throws NoSuchMethodException {
|
||||
return testTarget.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());
|
||||
}
|
||||
|
||||
private Object invokeMethod(T testTarget, Object[] inputs, Method newInstanceMethod) throws IllegalAccessException {
|
||||
Object output;
|
||||
try {
|
||||
output = newInstanceMethod.invoke(testTarget, inputs);
|
||||
} catch (InvocationTargetException i) {
|
||||
output = createOutputFromException(i);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private Object createOutputFromException(InvocationTargetException i) {
|
||||
Object output;
|
||||
StackTraceElement stacktraceElement = i.getTargetException().getStackTrace()[0];
|
||||
String info = stacktraceElement.getClassName() + ":" + stacktraceElement.getLineNumber();
|
||||
output = i.getTargetException().getClass().getName() + "(" + i.getTargetException().getMessage() + ") at "
|
||||
+ info;
|
||||
return output;
|
||||
}
|
||||
|
||||
private InputStream getTargetClass() {
|
||||
String resource = '/' + testTarget.getName().replace('.', '/') + ".class";
|
||||
return getClass().getResourceAsStream(resource);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import nl.jssl.autounit.util.LinkedList;
|
||||
|
||||
public class InAndOutput {
|
||||
private final LinkedList input;
|
||||
private final Object output;
|
||||
|
||||
public InAndOutput(LinkedList input, Object output) {
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public LinkedList getInput() {
|
||||
return input;
|
||||
}
|
||||
|
||||
public Object getOutput() {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import org.jacoco.core.analysis.IClassCoverage;
|
||||
|
||||
class InvocationResult {
|
||||
private final IClassCoverage coverage;
|
||||
private final Object output;
|
||||
|
||||
public InvocationResult(IClassCoverage coverage, Object output) {
|
||||
super();
|
||||
this.coverage = coverage;
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public IClassCoverage getCoverage() {
|
||||
return coverage;
|
||||
}
|
||||
|
||||
public Object getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.jacoco.core.analysis.IClassCoverage;
|
||||
|
||||
import nl.jssl.autounit.util.LinkedList;
|
||||
|
||||
public class MethodExecutionResults implements Comparable<MethodExecutionResults> {
|
||||
private transient Object testinstance;
|
||||
private transient Method executedMethod;
|
||||
private List<InAndOutput> contents = new ArrayList<InAndOutput>();
|
||||
private transient IClassCoverage coverageResult;
|
||||
|
||||
public MethodExecutionResults(Object testClass, Method m) {
|
||||
super();
|
||||
this.testinstance = testClass;
|
||||
this.executedMethod = m;
|
||||
}
|
||||
|
||||
public void addResult(LinkedList input, Object output) {
|
||||
contents.add(new InAndOutput(input, output));
|
||||
}
|
||||
|
||||
public List<InAndOutput> getContents() {
|
||||
return contents;
|
||||
}
|
||||
|
||||
public Object getTestinstance() {
|
||||
return testinstance;
|
||||
}
|
||||
|
||||
public Method getExecutedMethod() {
|
||||
return executedMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getReport();
|
||||
}
|
||||
|
||||
public void setCoverageResult(IClassCoverage coverageResult) {
|
||||
this.coverageResult = coverageResult;
|
||||
}
|
||||
|
||||
public IClassCoverage getCoverageResult() {
|
||||
return coverageResult;
|
||||
}
|
||||
|
||||
public String getReport() {
|
||||
StringBuilder s = new StringBuilder();
|
||||
for (InAndOutput inAndOutput : contents) {
|
||||
s.append(inAndOutput.getInput() + " => " + inAndOutput.getOutput() + "\n");
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public String getMethodSignature() {
|
||||
return getMethodSignature(executedMethod);
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return executedMethod.getName();
|
||||
}
|
||||
|
||||
private String getMethodSignature(Method m) {
|
||||
String signature = Modifier.toString(m.getModifiers()) + " " + m.getReturnType().getName() + " " + m.getName()
|
||||
+ "(";
|
||||
int index = 1;
|
||||
Class<?>[] parameterTypes = m.getParameterTypes();
|
||||
for (Class<?> type : parameterTypes) {
|
||||
signature += type.getName() + " arg" + (index++);
|
||||
if (index <= parameterTypes.length) {
|
||||
signature += ",";
|
||||
}
|
||||
}
|
||||
signature += ")";
|
||||
return signature;
|
||||
}
|
||||
|
||||
public Class<?> getMethodReturnType() {
|
||||
return executedMethod.getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MethodExecutionResults o) {
|
||||
return getMethodName().compareTo(o.getMethodName());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import nl.jssl.autounit.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Executes 1 method using alternating input parameters and yields execution
|
||||
* results.
|
||||
*/
|
||||
public class MethodcallExecutor<T> {
|
||||
private T instrumentedTestTarget;
|
||||
private Method methodUnderTest;
|
||||
private MethodExecutionResults result;
|
||||
private final CoverageAnalyser<T> coverageAnalyser;
|
||||
|
||||
public MethodcallExecutor(Class<T> testClass, Method methodUnderTest) {
|
||||
coverageAnalyser = new CoverageAnalyser<T>(testClass);
|
||||
this.instrumentedTestTarget = coverageAnalyser.instrument();
|
||||
|
||||
this.methodUnderTest = methodUnderTest;
|
||||
this.result = new MethodExecutionResults(instrumentedTestTarget, methodUnderTest);
|
||||
}
|
||||
|
||||
public MethodExecutionResults executeAndGetResults(List<LinkedList> inputs) {
|
||||
InvocationResult lastInvocationResult = null, previous = null;
|
||||
|
||||
int missedLines = Integer.MAX_VALUE;
|
||||
for (LinkedList input : inputs) {
|
||||
previous = lastInvocationResult;
|
||||
|
||||
lastInvocationResult = analyseMethodCall(methodUnderTest, input);
|
||||
|
||||
int missedCount = lastInvocationResult.getCoverage().getLineCounter().getMissedCount();
|
||||
|
||||
missedLines = addInOutputCombinationWhenCoverageIncreases(missedLines, lastInvocationResult, input,
|
||||
missedCount);
|
||||
|
||||
if (fullyCoveraged(missedCount)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lastInvocationResult != null) {
|
||||
if (previous == null) {
|
||||
result.setCoverageResult(lastInvocationResult.getCoverage());
|
||||
} else {
|
||||
result.setCoverageResult(previous.getCoverage());
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private int addInOutputCombinationWhenCoverageIncreases(int missedLines, InvocationResult lastInvocationResult,
|
||||
LinkedList input, int missedCount) {
|
||||
if (coverageHasIncreased(missedLines, missedCount)) {
|
||||
missedLines = missedCount;
|
||||
addInterestingInAndOutput(input, lastInvocationResult);
|
||||
}
|
||||
return missedLines;
|
||||
}
|
||||
|
||||
private void addInterestingInAndOutput(LinkedList input, InvocationResult lastInvocationResult) {
|
||||
result.addResult(input, lastInvocationResult.getOutput());
|
||||
}
|
||||
|
||||
private boolean fullyCoveraged(int missedCount) {
|
||||
return missedCount == 0;
|
||||
}
|
||||
|
||||
private boolean coverageHasIncreased(int missedLines, int missedCount) {
|
||||
return missedCount < missedLines;
|
||||
}
|
||||
|
||||
private InvocationResult analyseMethodCall(Method methodUnderTest, LinkedList input) {
|
||||
Object[] inputs = replaceNullIndicatorWithNull(input.toArray());
|
||||
|
||||
return coverageAnalyser.analyse(instrumentedTestTarget, methodUnderTest, inputs);
|
||||
}
|
||||
|
||||
private Object[] replaceNullIndicatorWithNull(Object[] argumentarray) {
|
||||
for (int i = 0; i < argumentarray.length; i++) {
|
||||
if (argumentarray[i].toString().equals("autounit:[NULL]")) {
|
||||
argumentarray[i] = null;
|
||||
}
|
||||
}
|
||||
return argumentarray;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,28 +9,30 @@ import java.util.Map;
|
|||
|
||||
import nl.jssl.autounit.inputs.objects.ObjectArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.objects.StringArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primtives.ArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primtives.BooleanArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primtives.ByteArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primtives.DoubleArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primtives.FloatArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primtives.IntegerArgumentFactory;
|
||||
import nl.jssl.autounit.utils.Permuter;
|
||||
import nl.jssl.autounit.utils.Permuter.Tuple;
|
||||
import nl.jssl.autounit.inputs.primitives.ArgumentFactory;
|
||||
import nl.jssl.autounit.inputs.primitives.BooleanArgumentFactory;
|
||||
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.LinkedList;
|
||||
import nl.jssl.autounit.util.Permuter;
|
||||
|
||||
public class MethodcallArgumentsFactory {
|
||||
private final Map<Class<?>, ArgumentFactory<?>> primitivesFactories;
|
||||
private final Class<?> testTarget;
|
||||
|
||||
public MethodcallArgumentsFactory() {
|
||||
public MethodcallArgumentsFactory(Class<?> testTarget) {
|
||||
this.testTarget = testTarget;
|
||||
primitivesFactories = new HashMap<Class<?>, ArgumentFactory<?>>();
|
||||
populateFactories();
|
||||
}
|
||||
|
||||
public List<Tuple> getInputs(Class<?> testTarget, Method m) {
|
||||
return combine(getArgumentsForAllParameters(testTarget, m));
|
||||
public List<LinkedList> getInputs(Method method) {
|
||||
return combine(getArgumentsForAllParameters(method));
|
||||
}
|
||||
|
||||
private List<Tuple> combine(List<List<?>> inputSetsForAllArguments) {
|
||||
private List<LinkedList> combine(List<List<?>> inputSetsForAllArguments) {
|
||||
int nrOfParameters = inputSetsForAllArguments.size();
|
||||
if (nrOfParameters == 0) {
|
||||
return Collections.emptyList();
|
||||
|
|
@ -42,25 +44,25 @@ public class MethodcallArgumentsFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private List<Tuple> makeArgumentsForSingleParameterCall(List<List<?>> generatedInputSetsForAllArguments) {
|
||||
List<Tuple> allPossibleArguments = new ArrayList<Tuple>();
|
||||
private List<LinkedList> makeArgumentsForSingleParameterCall(List<List<?>> generatedInputSetsForAllArguments) {
|
||||
List<LinkedList> allPossibleArguments = new ArrayList<>();
|
||||
|
||||
List<?> generatedInputs = generatedInputSetsForAllArguments.iterator().next();
|
||||
|
||||
for (Object variable : generatedInputs) {
|
||||
Tuple argument = new Tuple(variable);
|
||||
LinkedList argument = new LinkedList(variable);
|
||||
allPossibleArguments.add(argument);
|
||||
}
|
||||
return allPossibleArguments;
|
||||
}
|
||||
|
||||
List<List<?>> getArgumentsForAllParameters(Class<?> testTarget, Method m) {
|
||||
List<List<?>> getArgumentsForAllParameters(Method method) {
|
||||
List<List<?>> singleInputSets = new ArrayList<List<?>>();
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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<Object> inputs = new ArgumentsForSingleParameter<Object>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,24 @@
|
|||
package nl.jssl.autounit.inputs.objects;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
import nl.jssl.autounit.inputs.primtives.ArgumentFactory;
|
||||
import nl.jssl.autounit.utils.ConstantpoolReader;
|
||||
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<String> {
|
||||
private static ConstantpoolReader constantpoolReader = new ConstantpoolReader(ClassPool.getDefault());
|
||||
|
||||
@Override
|
||||
public ArgumentsForSingleParameter<String> getInputs(Class<?> testTarget) {
|
||||
ArgumentsForSingleParameter<String> inputs = new ArgumentsForSingleParameter<String>();
|
||||
inputs.add(null);
|
||||
inputs.add("some");
|
||||
inputs.addAll(constantpoolReader.scanStrings(testTarget));
|
||||
inputs.addAll(new ConstantpoolReader(testTarget).scanStrings());
|
||||
return inputs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.inputs.primtives;
|
||||
package nl.jssl.autounit.inputs.primitives;
|
||||
|
||||
import nl.jssl.autounit.inputs.ArgumentsForSingleParameter;
|
||||
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
package nl.jssl.autounit.results;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import nl.jssl.autounit.classanalyser.ClassResults;
|
||||
import nl.jssl.autounit.classanalyser.InAndOutput;
|
||||
import nl.jssl.autounit.classanalyser.MethodExecutionResults;
|
||||
|
||||
public class JUnitSourceWriter extends ResultsWriter {
|
||||
|
||||
public JUnitSourceWriter(PrintStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ClassResults results) {
|
||||
writeTestClass(results);
|
||||
}
|
||||
|
||||
private void writeTestClass(ClassResults results) {
|
||||
out.println("package " + results.getType().getPackage().getName() + ";");
|
||||
out.println();
|
||||
out.println("import static org.junit.Assert.assertEquals;");
|
||||
out.println("import org.junit.Test;");
|
||||
out.println();
|
||||
out.println("public class " + results.getType().getSimpleName() + "Tests {");
|
||||
Count index = new Count(1);
|
||||
for (MethodExecutionResults mcr : results.getMethodCallResults()) {
|
||||
for (InAndOutput inout : mcr.getContents()) {
|
||||
writeMethod(index, results, mcr, inout);
|
||||
}
|
||||
}
|
||||
|
||||
out.println("}");
|
||||
}
|
||||
|
||||
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();
|
||||
out.print("\t\tassertEquals(new " + results.getType().getSimpleName() + "()." + mcr.getMethodName() + "(");
|
||||
int nrArguments = inout.getInput().depth();
|
||||
int argumentCount = 1;
|
||||
for (Object o : inout.getInput()) {
|
||||
out.print(toString(o.getClass(), o));
|
||||
if ((argumentCount++) < nrArguments) {
|
||||
out.print(",");
|
||||
}
|
||||
}
|
||||
out.print("), ");
|
||||
out.print(toString(mcr.getMethodReturnType(), inout.getOutput()));
|
||||
out.println(");");
|
||||
out.println("\t}");
|
||||
}
|
||||
|
||||
private String toString(Class<?> type, Object object) {
|
||||
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";
|
||||
} else if (type == Byte.class || type == byte.class) {
|
||||
return "(byte)" + object.toString();
|
||||
} else if (type == Integer.class || type == int.class) {
|
||||
return object.toString();
|
||||
} else if (type == Float.class || type == float.class) {
|
||||
return object.toString() + "F";
|
||||
} else if (type == Short.class || type == short.class) {
|
||||
return "(short)" + object.toString();
|
||||
} else if (type == Character.class || type == char.class) {
|
||||
return "'" + object.toString() + "'";
|
||||
} else
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
static class Count {
|
||||
private int value;
|
||||
|
||||
public Count(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
value++;
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/main/java/nl/jssl/autounit/results/ResultsWriter.java
Normal file
16
src/main/java/nl/jssl/autounit/results/ResultsWriter.java
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package nl.jssl.autounit.results;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import nl.jssl.autounit.classanalyser.ClassResults;
|
||||
|
||||
public abstract class ResultsWriter {
|
||||
protected PrintStream out;
|
||||
|
||||
public ResultsWriter(PrintStream out) {
|
||||
super();
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
public abstract void write(ClassResults classResults);
|
||||
}
|
||||
56
src/main/java/nl/jssl/autounit/util/ConstantpoolReader.java
Normal file
56
src/main/java/nl/jssl/autounit/util/ConstantpoolReader.java
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
package nl.jssl.autounit.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.NotFoundException;
|
||||
import javassist.bytecode.ConstPool;
|
||||
|
||||
/**
|
||||
* Reads the constantpool of a class (see jvm spec)
|
||||
*/
|
||||
public class ConstantpoolReader {
|
||||
|
||||
private final static ClassPool pool;
|
||||
private final Class<?> classToRead;
|
||||
private final List<String> strings = new ArrayList<String>();
|
||||
|
||||
static {
|
||||
pool = ClassPool.getDefault();
|
||||
}
|
||||
|
||||
public ConstantpoolReader(Class<?> classToRead) {
|
||||
this.classToRead = classToRead;
|
||||
}
|
||||
|
||||
public List<String> scanStrings() {
|
||||
CtClass ctClass;
|
||||
try {
|
||||
ctClass = pool.get(classToRead.getName());
|
||||
if (isScannable(ctClass)) {
|
||||
ConstPool constPool = ctClass.getClassFile().getConstPool();
|
||||
doScanStrings(constPool);
|
||||
}
|
||||
return strings;
|
||||
} catch (NotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
81
src/main/java/nl/jssl/autounit/util/LinkedList.java
Normal file
81
src/main/java/nl/jssl/autounit/util/LinkedList.java
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
package nl.jssl.autounit.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public class LinkedList implements Iterable<Object> {
|
||||
public final Object element1;
|
||||
public final Object element2;
|
||||
|
||||
public LinkedList(Object element1) {
|
||||
this.element1 = element1;
|
||||
this.element2 = null;
|
||||
}
|
||||
|
||||
public LinkedList(Object element1, Object element2) {
|
||||
super();
|
||||
this.element1 = element1;
|
||||
this.element2 = element2;
|
||||
}
|
||||
|
||||
public int depth() {
|
||||
int d = 0;
|
||||
if (element2 != null) {
|
||||
if (element2 instanceof LinkedList) {
|
||||
d += 1 + ((LinkedList) element2).depth();
|
||||
} else {
|
||||
d += 1;
|
||||
}
|
||||
}
|
||||
if (element1 != null) {
|
||||
if (element1 instanceof LinkedList) {
|
||||
d += 1 + ((LinkedList) element1).depth();
|
||||
} else {
|
||||
d += 1;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Object> iterator() {
|
||||
return asList().iterator();
|
||||
}
|
||||
|
||||
private List<Object> asList() {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
if (element1 != null) {
|
||||
add(element1, list);
|
||||
} else {
|
||||
add("autounit:[NULL]", list);
|
||||
}
|
||||
if (element2 != null) {
|
||||
add(element2, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void add(Object element, List<Object> list) {
|
||||
if (element instanceof LinkedList) {
|
||||
LinkedList pair = (LinkedList) element;
|
||||
add(pair.element1, list);
|
||||
add(pair.element2, list);
|
||||
} else {
|
||||
list.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String string = "";
|
||||
for (Object o : this) {
|
||||
string += o.toString() + "-";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return asList().toArray();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package nl.jssl.autounit.utils;
|
||||
package nl.jssl.autounit.util;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
42
src/main/java/nl/jssl/autounit/util/Permuter.java
Normal file
42
src/main/java/nl/jssl/autounit/util/Permuter.java
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
package nl.jssl.autounit.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Makes permutations of n lists of m elements, ie:
|
||||
*
|
||||
* [A,B], [1,2] => [A,1], [A,2], [B,1], [B,2]
|
||||
*/
|
||||
public class Permuter {
|
||||
|
||||
public static List<LinkedList> permute(List<List<?>> elements) {
|
||||
if (elements.size() >= 2) {
|
||||
List<LinkedList> result = permutePairs(elements.remove(0), elements.remove(0));
|
||||
|
||||
result = permuteRest(elements, result);
|
||||
|
||||
return result;
|
||||
} else {
|
||||
throw new IllegalArgumentException("need at least 2");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<LinkedList> permuteRest(List<List<?>> elements, List<LinkedList> result) {
|
||||
for (List<?> element : elements) {
|
||||
result = permutePairs(element, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static List<LinkedList> permutePairs(List<?> list1, List<?> list2) {
|
||||
List<LinkedList> pairs = new ArrayList<LinkedList>();
|
||||
for (Object element1 : list1) {
|
||||
for (Object element2 : list2) {
|
||||
pairs.add(new LinkedList(element1, element2));
|
||||
}
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
}
|
||||
37
src/main/java/nl/jssl/autounit/util/SilentObjectCreator.java
Normal file
37
src/main/java/nl/jssl/autounit/util/SilentObjectCreator.java
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* Creates Objects from any class.
|
||||
*
|
||||
* Kindly copied from http://www.javaspecialists.eu/archive/Issue175.html
|
||||
*/
|
||||
public class SilentObjectCreator {
|
||||
public static <T> T create(Class<T> clazz) {
|
||||
return create(clazz, Object.class);
|
||||
}
|
||||
|
||||
public static <T> T create(Class<T> clazz, Class<? super T> parent) {
|
||||
try {
|
||||
return tryCreateInstance(clazz, parent);
|
||||
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException
|
||||
| InvocationTargetException e) {
|
||||
throw new AnalysisFailed("Cannot create object", e);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T tryCreateInstance(Class<T> clazz, Class<? super T> parent)
|
||||
throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
|
||||
ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
|
||||
Constructor<?> objDef = parent.getDeclaredConstructor();
|
||||
Constructor<T> intConstr = (Constructor<T>) reflectionFactory.newConstructorForSerialization(clazz, objDef);
|
||||
return clazz.cast(intConstr.newInstance());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
package nl.jssl.autounit.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import javassist.CtClass;
|
||||
import javassist.NotFoundException;
|
||||
import javassist.bytecode.ConstPool;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ConstantpoolReader {
|
||||
|
||||
private ClassPool pool;
|
||||
|
||||
public ConstantpoolReader(ClassPool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public List<String> scanStrings(Class<?> target) {
|
||||
CtClass ctClass;
|
||||
try {
|
||||
ctClass = pool.get(target.getName());
|
||||
List<String> strings = new ArrayList<String>();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
return strings;
|
||||
} catch (NotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isScannable(CtClass ctClass) {
|
||||
return !ctClass.isFrozen();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
package nl.jssl.autounit.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Makes permutations of n lists of m elements, ie:
|
||||
*
|
||||
* [A,B], [1,2] => [A,1], [A,2], [B,1], [B,2]
|
||||
*/
|
||||
public class Permuter {
|
||||
|
||||
public static List<Tuple> permute(List<List<?>> elements) {
|
||||
if (elements.size() >= 2) {
|
||||
List<Tuple> result = permutePairs(elements.remove(0), elements.remove(0));
|
||||
|
||||
for (List<?> element : elements) {
|
||||
result = permutePairs(element, result);
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
throw new IllegalArgumentException("need at least 2");
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Tuple> permutePairs(List<?> list1, List<?> list2) {
|
||||
List<Tuple> pairs = new ArrayList<Tuple>();
|
||||
for (Object element1 : list1) {
|
||||
for (Object element2 : list2) {
|
||||
pairs.add(new Tuple(element1, element2));
|
||||
}
|
||||
}
|
||||
return pairs;
|
||||
}
|
||||
|
||||
public static class Tuple implements Iterable<Object> {
|
||||
public final Object element1;
|
||||
public final Object element2;
|
||||
|
||||
public Tuple(Object element1) {
|
||||
this.element1 = element1;
|
||||
this.element2 = null;
|
||||
}
|
||||
|
||||
public Tuple(Object element1, Object element2) {
|
||||
super();
|
||||
this.element1 = element1;
|
||||
this.element2 = element2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Object> iterator() {
|
||||
return asList().iterator();
|
||||
}
|
||||
|
||||
private List<Object> asList() {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
if (element1 != null) {
|
||||
add(element1, list);
|
||||
} else {
|
||||
add("autounit:[NULL]", list);
|
||||
}
|
||||
if (element2 != null) {
|
||||
add(element2, list);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void add(Object element, List<Object> list) {
|
||||
if (!(element instanceof Tuple)) {
|
||||
list.add(element);
|
||||
} else {
|
||||
Tuple pair = (Tuple) element;
|
||||
add(pair.element1, list);
|
||||
add(pair.element2, list);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String string = "";
|
||||
for (Object o : this) {
|
||||
string += o.toString() + "-";
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return asList().toArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package nl.jssl.autounit.utils;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import sun.reflect.ReflectionFactory;
|
||||
|
||||
/**
|
||||
* Creates Objects from any class.
|
||||
*
|
||||
* Kindly copied from http://www.javaspecialists.eu/archive/Issue175.html
|
||||
*/
|
||||
public class SilentObjectCreator {
|
||||
public static <T> T create(Class<T> clazz) {
|
||||
return create(clazz, Object.class);
|
||||
}
|
||||
|
||||
public static <T> T create(Class<T> clazz, Class<? super T> parent) {
|
||||
try {
|
||||
ReflectionFactory rf = ReflectionFactory.getReflectionFactory();
|
||||
Constructor<?> objDef = parent.getDeclaredConstructor();
|
||||
Constructor<T> intConstr = (Constructor<T>) rf.newConstructorForSerialization(clazz, objDef);
|
||||
return clazz.cast(intConstr.newInstance());
|
||||
} catch (RuntimeException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Cannot create object", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package nl.jssl.autounit.utils;
|
||||
|
||||
import nl.jssl.autounit.utils.Permuter.Tuple;
|
||||
|
||||
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 == Tuple.class);
|
||||
}
|
||||
|
||||
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
|
||||
Tuple arguments = (Tuple) 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package nl.jssl.autounit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import nl.jssl.autounit.testclasses.BooleanArguments;
|
||||
import nl.jssl.autounit.testclasses.ByteArguments;
|
||||
import nl.jssl.autounit.testclasses.FloatArguments;
|
||||
import nl.jssl.autounit.testclasses.IntArguments;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PrimtiveTypeTests {
|
||||
@Test
|
||||
public void testGetPublicMethods() throws NoSuchMethodException, SecurityException {
|
||||
List<Method> publicMethods = new Recorder(IntArguments.class).getPublicMethods();
|
||||
|
||||
assertEquals(2, publicMethods.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerArgument() {
|
||||
Map<String, MethodCallResults> results = new AutoTester().record(IntArguments.class);
|
||||
Set<String> keys = results.keySet();
|
||||
assertTrue(keys.contains("public java.lang.String evenOrUneven(int arg1,int arg2)"));
|
||||
MethodCallResults mcr = results.values().iterator().next();
|
||||
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
|
||||
System.out.println(mcr.getReport());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanArgument() {
|
||||
Map<String, MethodCallResults> results = new AutoTester().record(BooleanArguments.class);
|
||||
Set<String> keys = results.keySet();
|
||||
assertTrue(keys.contains("public java.lang.String getText(boolean arg1,boolean arg2)"));
|
||||
MethodCallResults mcr = results.values().iterator().next();
|
||||
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
|
||||
System.out.println(mcr.getReport());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testByteArgument() {
|
||||
Map<String, MethodCallResults> results = new AutoTester().record(ByteArguments.class);
|
||||
Set<String> keys = results.keySet();
|
||||
assertTrue(keys.contains("public int getDouble(byte arg1)"));
|
||||
MethodCallResults mcr = results.values().iterator().next();
|
||||
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
|
||||
System.out.println(mcr.getReport());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatArgument() {
|
||||
Map<String, MethodCallResults> results = new AutoTester().record(FloatArguments.class);
|
||||
Set<String> keys = results.keySet();
|
||||
assertTrue(keys.contains("public int round(float arg1)"));
|
||||
MethodCallResults mcr = results.values().iterator().next();
|
||||
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
|
||||
System.out.println(mcr.getReport());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import nl.jssl.autounit.testclasses.BooleanArguments;
|
||||
import nl.jssl.autounit.testclasses.ByteArguments;
|
||||
import nl.jssl.autounit.testclasses.FloatArguments;
|
||||
import nl.jssl.autounit.testclasses.IntArguments;
|
||||
|
||||
public class PrimtiveTypeTests {
|
||||
@Test
|
||||
public void testGetPublicMethods() throws NoSuchMethodException, SecurityException {
|
||||
List<Method> publicMethods = new ClassAnalyser<>(IntArguments.class).getPublicMethods();
|
||||
|
||||
assertEquals(2, publicMethods.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntegerArgument() {
|
||||
Iterator<MethodExecutionResults> methodCallResults = new TreeSet<>(
|
||||
new ClassAnalyser<>(IntArguments.class).analyseAndGetResults().getMethodCallResults()).iterator();
|
||||
|
||||
assertEquals("public java.lang.String evenOrUneven(int arg1,int arg2)",
|
||||
methodCallResults.next().getMethodSignature());
|
||||
assertEquals("public int randomOther(int arg1)", methodCallResults.next().getMethodSignature());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBooleanArgument() {
|
||||
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() {
|
||||
MethodExecutionResults mcr = new ClassAnalyser<>(ByteArguments.class).analyseAndGetResults().getMethodCallResults()
|
||||
.get(0);
|
||||
assertEquals(mcr.getMethodSignature(), "public int getDouble(byte arg1)");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFloatArgument() {
|
||||
MethodExecutionResults mcr = new ClassAnalyser<>(FloatArguments.class).analyseAndGetResults().getMethodCallResults()
|
||||
.get(0);
|
||||
assertEquals(mcr.getMethodSignature(), "public int round(float arg1)");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,23 +1,22 @@
|
|||
package nl.jssl.autounit;
|
||||
package nl.jssl.autounit.classanalyser;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import nl.jssl.autounit.testclasses.StringArguments;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import nl.jssl.autounit.testclasses.StringArguments;
|
||||
|
||||
public class StringTypeTests {
|
||||
|
||||
@Test
|
||||
public void testStringArgumentShouldBeTjeempie() {
|
||||
Map<String, MethodCallResults> results = new AutoTester().record(StringArguments.class);
|
||||
Set<String> keys = results.keySet();
|
||||
String methodSignature = keys.iterator().next();
|
||||
List<MethodExecutionResults> 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);
|
||||
MethodCallResults mcr = results.values().iterator().next();
|
||||
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
|
||||
System.out.println(mcr.getReport());
|
||||
}
|
||||
|
|
@ -28,7 +27,8 @@ public class StringTypeTests {
|
|||
// Map<String, MethodCallResults> results = new
|
||||
// AutoTester().record(MethodSignatureMaker.class);
|
||||
// Set<String> keys = results.keySet();
|
||||
// assertTrue(keys.contains("public java.lang.String getMethodSignature(java.lang.reflect.Method arg1)"));
|
||||
// assertTrue(keys.contains("public java.lang.String
|
||||
// getMethodSignature(java.lang.reflect.Method arg1)"));
|
||||
// MethodCallResults mcr = results.values().iterator().next();
|
||||
// System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount()
|
||||
// + " missed lines");
|
||||
|
|
@ -1,23 +1,34 @@
|
|||
package nl.jssl.autounit.inputs.objects;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import nl.jssl.autounit.AutoTester;
|
||||
import nl.jssl.autounit.MethodCallResults;
|
||||
import nl.jssl.autounit.testclasses.SomeBean;
|
||||
import java.util.Iterator;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import nl.jssl.autounit.JUnitTestCreator;
|
||||
import nl.jssl.autounit.classanalyser.ClassAnalyser;
|
||||
import nl.jssl.autounit.classanalyser.MethodExecutionResults;
|
||||
import nl.jssl.autounit.testclasses.SomeBean;
|
||||
|
||||
public class JavaBeanTests {
|
||||
@Test
|
||||
public void testJavaBeanArgument() {
|
||||
Map<String, MethodCallResults> results = new AutoTester().record(SomeBean.class);
|
||||
Set<String> keys = results.keySet();
|
||||
Assert.assertTrue(keys.contains("public void setFoo(java.lang.String arg1)"));
|
||||
MethodCallResults mcr = results.values().iterator().next();
|
||||
System.out.println(mcr.getCoverageResult().getLineCounter().getMissedCount() + " missed lines");
|
||||
System.out.println(mcr.getReport());
|
||||
Iterator<MethodExecutionResults> results = getSortedAnalysisResults().iterator();
|
||||
|
||||
assertEquals("public int getBar()", results.next().getMethodSignature());
|
||||
assertEquals("public java.lang.String getFoo()", results.next().getMethodSignature());
|
||||
assertEquals("public void setBar(int arg1)", results.next().getMethodSignature());
|
||||
assertEquals("public void setFoo(java.lang.String arg1)", results.next().getMethodSignature());
|
||||
}
|
||||
|
||||
private TreeSet<MethodExecutionResults> getSortedAnalysisResults() {
|
||||
return new TreeSet<>(new ClassAnalyser<>(SomeBean.class).analyseAndGetResults().getMethodCallResults());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getUnittest() {
|
||||
new JUnitTestCreator<>(SomeBean.class).create();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -2,20 +2,17 @@ package nl.jssl.autounit.inspect;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import javassist.ClassPool;
|
||||
import org.junit.Test;
|
||||
|
||||
import javassist.NotFoundException;
|
||||
import nl.jssl.autounit.testclasses.IntArguments;
|
||||
import nl.jssl.autounit.utils.ConstantpoolReader;
|
||||
|
||||
import org.junit.Test;
|
||||
import nl.jssl.autounit.util.ConstantpoolReader;
|
||||
|
||||
public class ConstantpoolReaderTest {
|
||||
@Test
|
||||
public void test() throws NotFoundException {
|
||||
ClassPool classPool = new ClassPool();
|
||||
classPool.appendClassPath("c:\\workspaces\\autounit\\autounit\\bin");
|
||||
ConstantpoolReader reader = new ConstantpoolReader(classPool);
|
||||
List<String> strings = reader.scanStrings(IntArguments.class);
|
||||
ConstantpoolReader reader = new ConstantpoolReader(IntArguments.class);
|
||||
List<String> strings = reader.scanStrings();
|
||||
for (String string : strings) {
|
||||
System.out.println(string);
|
||||
}
|
||||
|
|
|
|||
25
src/test/java/nl/jssl/autounit/util/PairTests.java
Normal file
25
src/test/java/nl/jssl/autounit/util/PairTests.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package nl.jssl.autounit.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PairTests {
|
||||
@Test
|
||||
public void testDepth1() {
|
||||
LinkedList p = new LinkedList("1");
|
||||
assertEquals(1, p.depth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDepth2() {
|
||||
LinkedList p = new LinkedList(new LinkedList("1"));
|
||||
assertEquals(2, p.depth());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDepth3() {
|
||||
LinkedList p = new LinkedList(new LinkedList(new LinkedList("1")));
|
||||
assertEquals(3, p.depth());
|
||||
}
|
||||
}
|
||||
|
|
@ -5,9 +5,6 @@ import static org.junit.Assert.assertEquals;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import nl.jssl.autounit.utils.Permuter;
|
||||
import nl.jssl.autounit.utils.Permuter.Tuple;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class PermuterTests {
|
||||
|
|
@ -16,13 +13,16 @@ public class PermuterTests {
|
|||
List<Integer> integers = new ArrayList<Integer>();
|
||||
integers.add(1);
|
||||
integers.add(2);
|
||||
|
||||
List<String> strings = new ArrayList<String>();
|
||||
strings.add("A");
|
||||
strings.add("B");
|
||||
|
||||
List<List<?>> outer = new ArrayList<List<?>>();
|
||||
outer.add(integers);
|
||||
outer.add(strings);
|
||||
List<Tuple> permuted = Permuter.permute(outer);
|
||||
List<LinkedList> permuted = Permuter.permute(outer);
|
||||
|
||||
assertEquals("1-A-", permuted.get(0).toString());
|
||||
assertEquals("1-B-", permuted.get(1).toString());
|
||||
assertEquals("2-A-", permuted.get(2).toString());
|
||||
|
|
@ -46,7 +46,7 @@ public class PermuterTests {
|
|||
outer.add(strings);
|
||||
outer.add(vogons);
|
||||
|
||||
List<Tuple> permuted = Permuter.permute(outer);
|
||||
List<LinkedList> 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());
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ public class MyMethod {
|
|||
return 0;
|
||||
}
|
||||
|
||||
public Class getReturnType() {
|
||||
public Class<?> getReturnType() {
|
||||
return Void.class;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue