org.evosuite.testcase.DefaultTestCase Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2010-2018 Gordon Fraser, Andrea Arcuri and EvoSuite
* contributors
*
* This file is part of EvoSuite.
*
* EvoSuite is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3.0 of the License, or
* (at your option) any later version.
*
* EvoSuite is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with EvoSuite. If not, see .
*/
package org.evosuite.testcase;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.evosuite.assertion.Assertion;
import org.evosuite.assertion.InspectorAssertion;
import org.evosuite.assertion.PrimitiveFieldAssertion;
import org.evosuite.contracts.ContractViolation;
import org.evosuite.ga.ConstructionFailedException;
import org.evosuite.runtime.util.Inputs;
import org.evosuite.setup.TestClusterUtils;
import org.evosuite.testcase.statements.*;
import org.evosuite.testcase.statements.environment.AccessedEnvironment;
import org.evosuite.testcase.execution.CodeUnderTestException;
import org.evosuite.testcase.execution.Scope;
import org.evosuite.testcase.variable.*;
import org.evosuite.utils.generic.GenericClass;
import org.evosuite.utils.generic.GenericField;
import org.evosuite.utils.ListenableList;
import org.evosuite.utils.Listener;
import org.evosuite.utils.Randomness;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.googlecode.gentyref.GenericTypeReflector;
import org.springframework.util.ClassUtils;
/**
* A test case is a list of statements
*
* @author Gordon Fraser
*/
public class DefaultTestCase implements TestCase, Serializable {
private static final long serialVersionUID = -689512549778944250L;
private static final Logger logger = LoggerFactory.getLogger(DefaultTestCase.class);
protected static final AtomicInteger idGenerator = new AtomicInteger(0);
private final AccessedEnvironment accessedEnvironment = new AccessedEnvironment();
/** The statements */
protected final ListenableList statements;
/** Coverage goals this test covers */
private transient Set coveredGoals = new LinkedHashSet();
/** Violations revealed by this test */
private transient Set contractViolations = new LinkedHashSet();
private boolean isFailing = false;
private boolean unstable = false;
private int id;
/**
* Constructor
*/
public DefaultTestCase() {
statements = new ListenableList<>(new ArrayList<>());
id = idGenerator.getAndIncrement();
}
public int getID(){
return id;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#accept(org.evosuite.testcase.TestVisitor)
*/
/** {@inheritDoc} */
@Override
public void accept(TestVisitor visitor) {
visitor.visitTestCase(this);
Iterator iterator = statements.iterator();
while (iterator.hasNext()) {
Statement statement = iterator.next();
logger.trace("Visiting statement " + statement.getCode());
visitor.visitStatement(statement);
}
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#addAssertions(org.evosuite.testcase.DefaultTestCase)
*/
/** {@inheritDoc} */
@Override
public void addAssertions(TestCase other) {
for (int i = 0; i < statements.size() && i < other.size(); i++) {
for (Assertion a : other.getStatement(i).getAssertions()) {
if (!statements.get(i).getAssertions().contains(a))
if (a != null)
statements.get(i).getAssertions().add(a.clone(this));
}
}
}
@Override
public void addContractViolation(ContractViolation violation) {
contractViolations.add(violation);
}
@Override
public Set getContractViolations() {
return contractViolations;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#addCoveredGoal(org.evosuite.testcase.TestFitnessFunction)
*/
/** {@inheritDoc} */
@Override
public void addCoveredGoal(TestFitnessFunction goal) {
coveredGoals.add(goal);
// TODO: somehow adds the same goal more than once (fitnessfunction.equals()?)
}
@Override
public boolean isGoalCovered(TestFitnessFunction goal){
return coveredGoals.contains(goal);
}
private void addFields(List variables, VariableReference var,
Type type) {
if (!var.isPrimitive() && !(var instanceof NullReference)) {
// add fields of this object to list
for (Field field : TestClusterUtils.getAccessibleFields(var.getVariableClass())) {
Type fieldType = field.getType();
try {
fieldType = field.getGenericType();
} catch (java.lang.reflect.GenericSignatureFormatError e) {
// Ignore
fieldType = field.getType();
}
FieldReference f = new FieldReference(this, new GenericField(field,
var.getGenericClass()), fieldType, var);
if (f.getDepth() <= 2) {
if (type != null) {
if (f.isAssignableTo(type) && !variables.contains(f)) {
variables.add(f);
}
} else if (!variables.contains(f)) {
variables.add(f);
}
}
}
}
}
/** {@inheritDoc} */
@Override
public void addListener(Listener listener) {
statements.addListener(listener);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#addStatement(org.evosuite.testcase.Statement)
*/
/** {@inheritDoc} */
@Override
public VariableReference addStatement(Statement statement) {
statements.add(statement);
try {
assert (isValid());
} catch (AssertionError e) {
logger.info("Is not valid: ");
for (Statement s : statements) {
try {
logger.info(s.getCode());
} catch (AssertionError e2) {
logger.info("Found error in: " + s);
if (s instanceof MethodStatement) {
MethodStatement ms = (MethodStatement) s;
if (!ms.isStatic()) {
logger.info("Callee: ");
logger.info(ms.getCallee().toString());
}
int num = 0;
for (VariableReference v : ms.getParameterReferences()) {
logger.info("Parameter " + num);
logger.info(v.getVariableClass().toString());
logger.info(v.getClass().toString());
logger.info(v.toString());
}
}
}
}
assert (false);
}
return statement.getReturnValue();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#addStatement(org.evosuite.testcase.Statement, int)
*/
/** {@inheritDoc} */
@Override
public VariableReference addStatement(Statement statement, int position) {
statements.add(position, statement);
assert (isValid());
return statement.getReturnValue();
}
/** {@inheritDoc} */
@Override
public void addStatements(List extends Statement> statements) {
this.statements.addAll(statements);
}
/**
*
* changeClassLoader
*
*
* @param loader
* a {@link java.lang.ClassLoader} object.
*/
public void changeClassLoader(ClassLoader loader) {
changedClassLoader = loader;
for (Statement s : statements) {
s.changeClassLoader(loader);
}
}
private transient ClassLoader changedClassLoader = null;
public ClassLoader getChangedClassLoader() {
return changedClassLoader;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#chop(int)
*/
/** {@inheritDoc} */
@Override
public void chop(int length) {
while (statements.size() > length) {
statements.remove(length);
}
}
@Override
public int sliceFor(VariableReference var) {
Set dependentStatements = new LinkedHashSet();
dependentStatements.add(statements.get(var.getStPosition()));
int lastPosition = var.getStPosition();
// Add all statements that use this var
for(VariableReference ref : getReferences(var)) {
if(ref.getStPosition() > lastPosition)
lastPosition = ref.getStPosition();
dependentStatements.add(statements.get(ref.getStPosition()));
}
for (int i = lastPosition; i >= 0; i--) {
Set newStatements = new LinkedHashSet();
for (Statement s : dependentStatements) {
if (s.references(statements.get(i).getReturnValue()) ||
s.references(statements.get(i).getReturnValue().getAdditionalVariableReference())) {
newStatements.add(statements.get(i));
break;
}
}
dependentStatements.addAll(newStatements);
}
List dependentPositions = new ArrayList();
for(Statement s : dependentStatements) {
dependentPositions.add(s.getPosition());
}
Collections.sort(dependentPositions, Collections.reverseOrder());
for(Integer pos = size(); pos >= 0 ; pos--) {
if(!dependentPositions.contains(pos)) {
remove(pos);
}
}
return var.getStPosition();
}
public boolean contains(Statement statement) {
for(Statement s : statements) {
if(s.equals(statement)) {
return true;
}
}
return false;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#clearCoveredGoals()
*/
/** {@inheritDoc} */
@Override
public void clearCoveredGoals() {
coveredGoals.clear();
}
/**
* {@inheritDoc}
*
* Create a copy of the test case
*/
@Override
public DefaultTestCase clone() {
DefaultTestCase t = null;
t = new DefaultTestCase(); //Note: cannot use super.clone() due to final fields :(
/*
try {
t = (DefaultTestCase) super.clone();
} catch (CloneNotSupportedException e) {
//shouldn't really happen
logger.error("Failed clone: "+e);
return null;
}
*/
for (Statement s : statements) {
Statement copy = s.clone(t);
t.statements.add(copy);
copy.setRetval(s.getReturnValue().clone(t));
copy.setAssertions(s.copyAssertions(t, 0));
}
t.coveredGoals.addAll(coveredGoals);
t.accessedEnvironment.copyFrom(accessedEnvironment);
t.isFailing = isFailing;
t.id = idGenerator.getAndIncrement(); //always create new ID when making a clone
//t.exception_statement = exception_statement;
//t.exceptionThrown = exceptionThrown;
return t;
}
/** {@inheritDoc} */
@Override
public void deleteListener(Listener listener) {
statements.deleteListener(listener);
}
/** {@inheritDoc} */
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DefaultTestCase other = (DefaultTestCase) obj;
if (statements == null) {
if (other.statements != null)
return false;
} else {
if (statements.size() != other.statements.size())
return false;
// if (!statements.equals(other.statements))
for (int i = 0; i < statements.size(); i++) {
if (!statements.get(i).equals(other.statements.get(i))) {
return false;
}
}
}
return true;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getAccessedClasses()
*/
/** {@inheritDoc} */
@Override
public Set> getAccessedClasses() {
Set> accessedClasses = new LinkedHashSet>();
for (Statement s : statements) {
for (VariableReference var : s.getVariableReferences()) {
if (var != null && !var.isPrimitive()) {
Class> clazz = var.getVariableClass();
while (clazz.isMemberClass()) {
//accessed_classes.add(clazz);
clazz = clazz.getEnclosingClass();
}
while (clazz.isArray())
clazz = clazz.getComponentType();
accessedClasses.add(clazz);
}
}
if (s instanceof MethodStatement) {
MethodStatement ms = (MethodStatement) s;
accessedClasses.addAll(Arrays.asList(ms.getMethod().getMethod().getExceptionTypes()));
accessedClasses.add(ms.getMethod().getMethod().getDeclaringClass());
accessedClasses.add(ms.getMethod().getMethod().getReturnType());
accessedClasses.addAll(Arrays.asList(ms.getMethod().getMethod().getParameterTypes()));
} else if (s instanceof FieldStatement) {
FieldStatement fs = (FieldStatement) s;
accessedClasses.add(fs.getField().getField().getDeclaringClass());
accessedClasses.add(fs.getField().getField().getType());
} else if (s instanceof ConstructorStatement) {
ConstructorStatement cs = (ConstructorStatement) s;
accessedClasses.add(cs.getConstructor().getConstructor().getDeclaringClass());
accessedClasses.addAll(Arrays.asList(cs.getConstructor().getConstructor().getExceptionTypes()));
accessedClasses.addAll(Arrays.asList(cs.getConstructor().getConstructor().getParameterTypes()));
}
}
return accessedClasses;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getAssertions()
*/
/** {@inheritDoc} */
@Override
public List getAssertions() {
List assertions = new ArrayList();
for (Statement s : statements) {
assertions.addAll(s.getAssertions());
}
return assertions;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getCoveredGoals()
*/
/** {@inheritDoc} */
@Override
public Set getCoveredGoals() {
return coveredGoals;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getDeclaredExceptions()
*/
/** {@inheritDoc} */
@Override
public Set> getDeclaredExceptions() {
Set> exceptions = new LinkedHashSet>();
for (Statement statement : statements) {
exceptions.addAll(statement.getDeclaredExceptions());
}
return exceptions;
}
@Override
public AccessedEnvironment getAccessedEnvironment() {
return accessedEnvironment;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getDependencies(org.evosuite.testcase.VariableReference)
*/
/** {@inheritDoc} */
@Override
public Set getDependencies(VariableReference var) {
Set dependencies = new LinkedHashSet();
if (var == null || var.getStPosition() == -1)
return dependencies;
Set dependentStatements = new LinkedHashSet();
if(statements.size() > var.getStPosition())
dependentStatements.add(statements.get(var.getStPosition()));
for (int i = var.getStPosition(); i >= 0; i--) {
Set newStatements = new LinkedHashSet();
for (Statement s : dependentStatements) {
if (s.references(statements.get(i).getReturnValue())) {
newStatements.add(statements.get(i));
dependencies.add(statements.get(i).getReturnValue());
break;
}
}
dependentStatements.addAll(newStatements);
}
return dependencies;
}
@Override
public VariableReference getLastObject(Type type) throws ConstructionFailedException {
return getLastObject(type, 0);
}
@Override
public VariableReference getLastObject(Type type, int position)
throws ConstructionFailedException {
for (int i = statements.size() - 1; i >= position; i--) {
Statement statement = statements.get(i);
VariableReference var = statement.getReturnValue();
if (var.isAssignableTo(type))
return var;
}
throw new ConstructionFailedException("Found no variables of type " + type);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getObject(org.evosuite.testcase.VariableReference, org.evosuite.testcase.Scope)
*/
/** {@inheritDoc} */
@Override
public Object getObject(VariableReference reference, Scope scope) {
try {
return reference.getObject(scope);
} catch (CodeUnderTestException e) {
throw new AssertionError("This case isn't handled yet");
}
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getObjects(int)
*/
/** {@inheritDoc} */
@Override
public List getObjects(int position) {
List variables = new LinkedList();
for (int i = 0; i < position && i < statements.size(); i++) {
VariableReference value = statements.get(i).getReturnValue();
if (value == null)
continue;
// TODO: Need to support arrays that were not self-created
if (value instanceof ArrayReference) { // &&
for (int index = 0; index < ((ArrayReference) value).getArrayLength(); index++) {
variables.add(new ArrayIndex(this, (ArrayReference) value, index));
}
} else if (!(value instanceof ArrayIndex)) {
variables.add(value);
addFields(variables, value, null);
}
// logger.trace(statements.get(i).retval.getSimpleClassName());
}
return variables;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getObjects(java.lang.reflect.Type, int)
*/
/** {@inheritDoc} */
@Override
public List getObjects(Type type, int position) {
List variables = new LinkedList();
GenericClass genericClass = new GenericClass(type);
Class> rawClass = genericClass.getRawClass();
for (int i = 0; i < position && i < size(); i++) {
Statement statement = statements.get(i);
if(statement instanceof MethodStatement) {
if(((MethodStatement)statement).getMethod().getName().equals("hashCode"))
continue;
}
VariableReference value = statement.getReturnValue();
if (value == null)
continue;
if (value instanceof ArrayReference) {
// For some reason, TypeUtils/ClassUtils sometimes claims
// that an array is assignable to its component type
// TODO: Fix
boolean isClassUtilsBug = false;
if (value.isArray()) {
Class> arrayClass = value.getVariableClass();
isClassUtilsBug = isClassUtilsBug(rawClass, arrayClass);
}
if (rawClass.isArray() && !isClassUtilsBug) {
isClassUtilsBug = isClassUtilsBug(value.getVariableClass(), rawClass);
}
if (value.isAssignableTo(type) && !isClassUtilsBug && value.isArray() == rawClass.isArray()) {
logger.debug("Array is assignable: " + value.getType() + " to "
+ type + ", " + value.isArray() + ", " + rawClass.isArray());
variables.add(value);
} else if (GenericClass.isAssignable(type, value.getComponentType())) {
Class> arrayClass = value.getComponentClass();
if (isClassUtilsBug(rawClass, arrayClass)) {
continue;
}
for (int index = 0; index < ((ArrayReference) value).getArrayLength(); index++) {
if (((ArrayReference) value).isInitialized(index, position))
variables.add(new ArrayIndex(this, (ArrayReference) value,
index));
}
}
} else if (value instanceof ArrayIndex) {
// Don't need to add this because array indices are created for array statement
} else if (value.isAssignableTo(type) && value.isPrimitive() == rawClass.isPrimitive() &&
value.isArray() == rawClass.isArray()) {
variables.add(value);
} else {
addFields(variables, value, type);
}
}
return variables;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getRandomObject(java.lang.reflect.Type, int)
*/
/** {@inheritDoc} */
@Override
public VariableReference getRandomNonNullNonPrimitiveObject(Type type, int position)
throws ConstructionFailedException {
Inputs.checkNull(type);
List variables = getObjects(type, position);
Iterator iterator = variables.iterator();
while (iterator.hasNext()) {
VariableReference var = iterator.next();
if (var instanceof NullReference)
iterator.remove();
else if (getStatement(var.getStPosition()) instanceof PrimitiveStatement)
iterator.remove();
else if (var.isPrimitive() || var.isWrapperType())
iterator.remove();
else if(this.getStatement(var.getStPosition()) instanceof FunctionalMockStatement && !(this.getStatement(var.getStPosition()) instanceof FunctionalMockForAbstractClassStatement))
iterator.remove();
}
if (variables.isEmpty())
throw new ConstructionFailedException("Found no variables of type " + type
+ " at position " + position);
return Randomness.choice(variables);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getRandomObject(java.lang.reflect.Type, int)
*/
/** {@inheritDoc} */
@Override
public VariableReference getRandomNonNullObject(Type type, int position)
throws ConstructionFailedException {
Inputs.checkNull(type);
List variables = getObjects(type, position);
Iterator iterator = variables.iterator();
while (iterator.hasNext()) {
VariableReference ref = iterator.next();
if (ref instanceof NullReference ||
(this.getStatement(ref.getStPosition()) instanceof FunctionalMockStatement) ) {
iterator.remove();
}
}
if (variables.isEmpty())
throw new ConstructionFailedException("Found no variables of type " + type
+ " at position " + position);
return Randomness.choice(variables);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getRandomObject()
*/
/** {@inheritDoc} */
@Override
public VariableReference getRandomObject() {
return getRandomObject(statements.size());
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getRandomObject(int)
*/
/** {@inheritDoc} */
@Override
public VariableReference getRandomObject(int position) {
List variables = getObjects(position);
if (variables.isEmpty())
return null;
return Randomness.choice(variables);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getRandomObject(java.lang.reflect.Type)
*/
/** {@inheritDoc} */
@Override
public VariableReference getRandomObject(Type type)
throws ConstructionFailedException {
return getRandomObject(type, statements.size());
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getRandomObject(java.lang.reflect.Type, int)
*/
/** {@inheritDoc} */
@Override
public VariableReference getRandomObject(Type type, int position)
throws ConstructionFailedException {
assert (type != null);
List variables = getObjects(type, position);
if (variables.isEmpty())
throw new ConstructionFailedException("Found no variables of type " + type
+ " at position " + position);
return Randomness.choice(variables);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getReferences(org.evosuite.testcase.VariableReference)
*/
/** {@inheritDoc} */
@Override
public Set getReferences(VariableReference var) {
Set references = new LinkedHashSet();
if (var == null || var.getStPosition() == -1)
return references;
// references.add(var);
for (int i = var.getStPosition() + 1; i < statements.size(); i++) {
Set temp = new LinkedHashSet();
if (statements.get(i).references(var))
temp.add(statements.get(i).getReturnValue());
else if (statements.get(i).references(var.getAdditionalVariableReference()))
temp.add(statements.get(i).getReturnValue());
for (VariableReference v : references) {
if (statements.get(i).references(v))
temp.add(statements.get(i).getReturnValue());
else if (statements.get(i).references(v.getAdditionalVariableReference()))
temp.add(statements.get(i).getReturnValue());
}
references.addAll(temp);
}
return references;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getReturnValue(int)
*/
/** {@inheritDoc} */
@Override
public VariableReference getReturnValue(int position) {
return getStatement(position).getReturnValue();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#getStatement(int)
*/
/** {@inheritDoc} */
@Override
public Statement getStatement(int position) {
if(position<0 || position>=statements.size()){
throw new IllegalArgumentException("Cannot access statement due to wrong position "
+position+", where total number of statements is "+statements.size());
}
return statements.get(position);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#hasStatement(int)
*/
/** {@inheritDoc} */
@Override
public boolean hasStatement(int position) {
return (statements.size() > position || position < 0);
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#hasAssertions()
*/
/** {@inheritDoc} */
@Override
public boolean hasAssertions() {
for (Statement s : statements) {
if (s.hasAssertions())
return true;
}
return false;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#hasCastableObject(java.lang.reflect.Type)
*/
/** {@inheritDoc} */
@Override
public boolean hasCastableObject(Type type) {
for (Statement st : statements) {
if (st.getReturnValue().isAssignableFrom(type)) {
return true;
}
}
return false;
}
/**
* {@inheritDoc}
*
* Equality check
*/
// public boolean equals(TestCase t) {
// return statements.size() == t.statements.size() && isPrefix(t);
// }
@Override
public int hashCode() {
return statements.hashCode();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#hasObject(java.lang.reflect.Type, int)
*/
/** {@inheritDoc} */
@Override
public boolean hasObject(Type type, int position) {
for (int i = 0; i < position && i < size(); i++) {
Statement st = statements.get(i);
if (st.getReturnValue() == null)
continue; // Nop
if (st.getReturnValue().isAssignableTo(type)) {
return true;
}
}
return false;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#hasReferences(org.evosuite.testcase.VariableReference)
*/
/** {@inheritDoc} */
@Override
public boolean hasReferences(VariableReference var) {
if (var == null || var.getStPosition() == -1)
return false;
for (int i = var.getStPosition() + 1; i < statements.size(); i++) {
if (statements.get(i).references(var))
return true;
}
for (Assertion assertion : statements.get(var.getStPosition()).getAssertions()) {
if (assertion.getReferencedVariables().contains(var))
return true;
}
return false;
}
private boolean isClassUtilsBug(Class> rawClass, Class> arrayClass) {
while (arrayClass != null && arrayClass.isArray()) {
if (rawClass.isAssignableFrom(arrayClass.getComponentType())) {
// if (arrayClass.getComponentType().equals(rawClass)) {
return true;
}
arrayClass = arrayClass.getComponentType();
}
return false;
}
@Override
public boolean isAccessible() {
for (Statement statement : statements) {
if (!statement.isAccessible())
return false;
}
return true;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#isEmpty()
*/
/** {@inheritDoc} */
@Override
public boolean isEmpty() {
return statements.isEmpty();
}
@Override
public boolean isFailing() {
return isFailing;
}
@Override
public void setFailing() {
isFailing = true;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#isPrefix(org.evosuite.testcase.DefaultTestCase)
*/
/** {@inheritDoc} */
@Override
public boolean isPrefix(TestCase t) {
if (statements.size() > t.size())
return false;
for (int i = 0; i < statements.size(); i++) {
if (!statements.get(i).same(t.getStatement(i))) {
return false;
}
}
return true;
}
@Override
public boolean isUnstable() {
return unstable;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#isValid()
*/
/** {@inheritDoc} */
@Override
public boolean isValid() {
for (Statement s : statements) {
assert (s.isValid()) : toCode();
}
return true;
}
/* (non-Javadoc)
* @see java.lang.Iterable#iterator()
*/
/** {@inheritDoc} */
@Override
public Iterator iterator() {
return statements.iterator();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#remove(int)
*/
/** {@inheritDoc} */
@Override
public void remove(int position) {
logger.debug("Removing statement {}", position);
if (position >= size()) {
return;
}
statements.remove(position);
assert (isValid());
// for(Statement s : statements) {
// for(Asss.assertions)
// }
}
@Override
public void removeAssertion(Assertion assertion) {
for (Statement s : statements) {
s.removeAssertion(assertion);
}
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#removeAssertions()
*/
/** {@inheritDoc} */
@Override
public void removeAssertions() {
for (Statement s : statements) {
s.removeAssertions();
}
}
private boolean methodNeedsDownCast(MethodStatement methodStatement, VariableReference var, Class> abstractClass) {
if(!methodStatement.isStatic() && methodStatement.getCallee().equals(var)) {
if(!ClassUtils.hasMethod(abstractClass, methodStatement.getMethod().getName(), methodStatement.getMethod().getRawParameterTypes())) {
// Need downcast for real
return true;
} else {
Method superClassMethod = ClassUtils.getMethod(abstractClass, methodStatement.getMethod().getName(), methodStatement.getMethod().getRawParameterTypes());
if(!methodStatement.getMethod().getRawGeneratedType().equals(superClassMethod.getReturnType())) {
// Overriding can also change return value, in which case we need to keep the downcast
return true;
}
}
}
List parameters = methodStatement.getParameterReferences();
Class>[] parameterTypes = methodStatement.getMethod().getRawParameterTypes();
for(int i = 0; i < parameters.size(); i++) {
VariableReference param = parameters.get(i);
if(param.equals(var) && !parameterTypes[i].isAssignableFrom(abstractClass)) {
// Need downcast for real
return true;
}
}
return false;
}
private boolean constructorNeedsDownCast(ConstructorStatement constructorStatement, VariableReference var, Class> abstractClass) {
List parameters = constructorStatement.getParameterReferences();
Class>[] parameterTypes = constructorStatement.getConstructor().getConstructor().getParameterTypes();
for(int i = 0; i < parameters.size(); i++) {
VariableReference param = parameters.get(i);
if(param.equals(var) && !parameterTypes[i].isAssignableFrom(abstractClass)) {
// Need downcast for real
return true;
}
}
return false;
}
private boolean fieldNeedsDownCast(FieldReference fieldReference, VariableReference var, Class> abstractClass) {
if(fieldReference.getSource().equals(var)) {
if(!fieldReference.getField().getDeclaringClass().isAssignableFrom(abstractClass)) {
// Need downcast for real
return true;
}
}
return false;
}
private boolean fieldNeedsDownCast(FieldStatement fieldStatement, VariableReference var, Class> abstractClass) {
if(!fieldStatement.isStatic() && fieldStatement.getSource().equals(var)) {
if(!fieldStatement.getField().getDeclaringClass().isAssignableFrom(abstractClass)) {
// Need downcast for real
return true;
}
}
return false;
}
private boolean assertionsNeedDownCast(Statement s, VariableReference var, Class> abstractClass) {
for(Assertion assertion : s.getAssertions()) {
if(assertion instanceof InspectorAssertion && assertion.getSource().equals(var)) {
InspectorAssertion inspectorAssertion = (InspectorAssertion)assertion;
Method inspectorMethod = inspectorAssertion.getInspector().getMethod();
if(!ClassUtils.hasMethod(abstractClass, inspectorMethod.getName(), inspectorMethod.getParameterTypes())) {
return true;
}
} else if(assertion instanceof PrimitiveFieldAssertion && assertion.getSource().equals(var)) {
PrimitiveFieldAssertion fieldAssertion = (PrimitiveFieldAssertion)assertion;
if(!fieldAssertion.getField().getDeclaringClass().isAssignableFrom(abstractClass)) {
return true;
}
}
}
return false;
}
public void removeDownCasts() {
for(Statement s : statements) {
if(s instanceof MethodStatement) {
MethodStatement ms = (MethodStatement)s;
VariableReference retVal = s.getReturnValue();
Class> variableClass = retVal.getVariableClass();
Class> methodReturnClass = ms.getMethod().getRawGeneratedType();
if(!variableClass.equals(methodReturnClass) && methodReturnClass.isAssignableFrom(variableClass)) {
logger.debug("Found downcast from {} to {}", methodReturnClass.getName(), variableClass);
if(assertionsNeedDownCast(ms, retVal, methodReturnClass)) {
return;
}
for(VariableReference ref : getReferences(retVal)) {
Statement usageStatement = statements.get(ref.getStPosition());
if(assertionsNeedDownCast(usageStatement, retVal, methodReturnClass)) {
return;
}
if(usageStatement instanceof MethodStatement) {
if(methodNeedsDownCast((MethodStatement)usageStatement, retVal, methodReturnClass)) {
return;
}
} else if(usageStatement instanceof ConstructorStatement) {
if(constructorNeedsDownCast((ConstructorStatement)usageStatement, retVal, methodReturnClass)) {
return;
}
} else if(usageStatement instanceof FieldStatement) {
if(fieldNeedsDownCast((FieldStatement)usageStatement, retVal, methodReturnClass)) {
return;
}
}
if(ref.isFieldReference()) {
if(fieldNeedsDownCast((FieldReference)ref, retVal, methodReturnClass)) {
return;
}
}
}
logger.debug("Downcast not needed, replacing with {}", ms.getMethod().getReturnType());
retVal.setType(ms.getMethod().getReturnType());
}
}
}
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#replace(org.evosuite.testcase.VariableReference, org.evosuite.testcase.VariableReference)
*/
/** {@inheritDoc} */
@Override
public void replace(VariableReference var1, VariableReference var2) {
for (Statement statement : statements) {
statement.replace(var1, var2);
}
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException,
IOException {
ois.defaultReadObject();
coveredGoals = new LinkedHashSet();
contractViolations = new LinkedHashSet();
}
public void setFailing(boolean failing) {
isFailing = failing;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#setStatement(org.evosuite.testcase.Statement, int)
*/
/** {@inheritDoc} */
@Override
public VariableReference setStatement(Statement statement, int position) {
statements.set(position, statement);
assert (isValid());
return statement.getReturnValue(); // TODO:
// -1?
}
@Override
public void setUnstable(boolean unstable) {
this.unstable = unstable;
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#size()
*/
/** {@inheritDoc} */
@Override
public int size() {
return statements.size();
}
/** {@inheritDoc} */
@Override
public int sizeWithAssertions() {
return this.size() + this.getAssertions().size();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#toCode()
*/
/** {@inheritDoc} */
@Override
public String toCode() {
TestCodeVisitor visitor = new TestCodeVisitor();
accept(visitor);
return visitor.getCode();
}
/* (non-Javadoc)
* @see org.evosuite.testcase.TestCase#toCode(java.util.Map)
*/
/** {@inheritDoc} */
@Override
public String toCode(Map exceptions) {
TestCodeVisitor visitor = new TestCodeVisitor();
visitor.setExceptions(exceptions);
accept(visitor);
return visitor.getCode();
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
/** {@inheritDoc} */
@Override
public String toString() {
return toCode();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy